Schmooze
Schmooze lets Ruby and Node.js work together intimately. It has a DSL that allows you to define what methods you need, and it executes code by spawning a Node.js process and sending messages back and forth.
Requirements
Schmooze requires that you have nodejs installed and in the $PATH
.
Gem Installation
Add this line to your application's Gemfile:
gem 'schmooze'
And then execute:
$ bundle
Usage
To use Schmooze, you first need to create a sublcass of Schmooze::Base
. Your subclass needs to list all of the package dependencies, and methods that you want to have available. For example, here is a Schmooze class that interfaces with Babel:
require 'schmooze'
class BabelSchmoozer < Schmooze::Base
dependencies babel: 'babel-core'
method :transform, 'babel.transform'
method :version, 'function() { return [process.version, babel.version]; }'
end
Note that the babel-core
package is available under the name babel
, because that's how we requested it.
To define a method, you simply give it a name and pass in a JavaScript string that should resolve to a function. Let's put this class to use!
First we need to make sure we install any needed packages.
$ npm install babel-core babel-preset-es2015
All we need to do next is to instantiate the class with a path to where the node modules are installed, and then we can call the methods! (Note that we need to pass in ast: false
because of a caveat).
$ pry
Ruby 2.2.2
pry> load './babel_schmoozer.rb'
pry> babel = BabelSchmoozer.new(__dir__)
pry> babel.version
=> ["v5.5.0", "6.5.2"]
pry> puts babel.transform('a = () => 1', ast: false, presets: ['es2015'])['code']
"use strict";
a = function a() {
return 1;
};
This could easily be turned into a Sprockets plugin.
Error handling
Errors happen, and Schmooze tries to make them as painless as possible to handle. If there is a dependency missing, Schmooze will throw a helpful Error when you try to initialize the class. Here is an example from the tests:
class ErrorSchmoozer < Schmooze::Base
dependencies nonexistant: 'this-package-is-not-here'
end
ErrorSchmoozer.new(__dir__)
This will raise
Schmooze::DependencyError: Cannot find module 'this-package-is-not-here'.
You need to add it to '/Users/bouke/code/schmooze/test/fixtures/uninstalled_package/package.json' and run 'npm install'
Any JavaScript errors that happen get converted to Ruby errors under the Schmooze::Javascript
namespace. For example (once again, from the tests):
class CoffeeSchmoozer < Schmooze::Base
dependencies coffee: 'coffee-script'
method :compile, 'coffee.compile'
end
CoffeeSchmoozer.new(__dir__).compile('<=> 1')
This will raise
Schmooze::JavaScript::SyntaxError: [stdin]:1:1: error: unexpected <=
<=> 1
^^
Caveats
- Because we serialize the return values from JavaScript to JSON, you can't return circular data structures (like the Babel AST).
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/schmooze.
Make sure the tests pass
Run the setup script
$ ./script/setup
Run the tests
$ ./script/test