Git Product home page Git Product logo

node-runner's Introduction

NodeRunner for Ruby

A simple way to execute Javascript in a Ruby context via Node. (Loosely based on the Node Runtime module from ExecJS.)

Gem Version

Installation

Run this command to add this plugin to your project's Gemfile:

$ bundle add node-runner

For Bridgetown websites, you can run an automation to install NodeRunner and set up a builder plugin for further customization.

bin/bridgetown apply https://github.com/bridgetownrb/node-runner

Usage

Simply create a new NodeRunner object and pass in the Javascript code you wish to execute:

require "node-runner"

runner = NodeRunner.new(
  <<~JAVASCRIPT
    const hello = (response) => {
      return `Hello? ${response}`
    }
  JAVASCRIPT
)

Then call the function as if it were a genuine Ruby method:

runner.hello "Goodbye!"

# output: "Hello? Goodbye!"

Under the hood, the data flowing in and out of the Javascript function is translated via JSON, so you'll need to stick to standard JSON-friendly data values (strings, integers, arrays, hashes, etc.)

You can also use Node require statements in your Javascript:

runner = NodeRunner.new(
  <<~JAVASCRIPT
    const path = require("path")
    const extname = (filename) => {
      return path.extname(filename);
    }
  JAVASCRIPT
)
  
extname = runner.extname("README.md")

extname == ".md"

# output: true

Multiple arguments for a function work, as do multiple function calls (aka if you define function_one and function_two in your Javascript, you can call runner.function_one or runner.function_two in Ruby).

Node Executor Options

If you need to customize which node binary is executed, or wish to use your own wrapper JS to bootstrap the node runtime, you can pass a custom instance of NodeRunner::Executor to NodeRunner:

NodeRunner.new "…", executor: NodeRunner::Executor.new(command: "/path/to/custom/node")

command can be an array as well, if you want to attempt multiple paths until one is found. Inspect the node-runner.rb source code for more information on the available options.

Caveats

A single run of a script is quite fast, nearly as fast as running a script directly with the node CLI…because that's essentially what is happening here. However, the performance characteristics using this in a high-traffic request/response cycle (say, from a Rails app) is unknown. Likely the best context to use Node Runner would be via a background job, or during a build process like when using a static site generator. (Like our parent project Bridgetown!)

Testing

  • Run bin/rake to run the test suite.

Contributing

  1. Fork it (https://github.com/bridgetownrb/node-runner/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

node-runner's People

Contributors

bglw avatar jaredcwhite avatar kdiogenes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

node-runner's Issues

Support methods that return a Promise

Hey,

I'm not much versed in JavaScript, but I think that this can be a good solution:

#{source}

try {
  const args = #{args}
  Promise.resolve(#{func}(...args)).then(result => {
    const output = JSON.stringify(['ok', result, []])
    process.stdout.write(output)
  })
} catch (err) {
  process.stdout.write(JSON.stringify(['err', '' + err, err.stack]))
}

I will write a PR with it, just would like to open the discussion.

Best regards!

Does node-runner use the same node instance?

Hello, I am interested if node-runner reuse the node instance between functions run?

# node is running and waiting for input?
runner = NodeRunner.new(
  <<~JAVASCRIPT
    const hello = (response) => {
      return `Hello? ${response}`
    }
  JAVASCRIPT
)

And do not bootstrap node on every function call

# These functions call do not launch node every time
runner.hello "Goodbye!"
runner.hello "Goodbye! 2"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.