erithmetic / nodeify

Bring the power of CommonJS, npm, and command-line testing to your Rails JavaScript
MIT License
45 stars 4 forks source link

nodeify

Bring CLI testing and npm modules to your Rails JavaScript.

What it does:

Why this is cool:

What this all means:

You'll have to wrap your head around the CommonJS/npm module system. It's quite a bit different than rubygems, but is a very clean module system.

Requirements

Install Node.js and npm:

$ port install nodejs
$ curl http://npmjs.org/install.sh | sh

Nodeify is designed to work with Rails 3.1 and higher.

Installation

In your Gemfile:

gem 'nodeify'

Run:

$ bundle update
$ rails g nodeify:install

Usage

App-specific JavaScript

As with any Rails JS with the asset pipeline, put your app-specific JavaScripts in app/assets/javascripts directory.

require()

Under the standard Rails asset pipeline regime, the Sprockets gem is used to manage JavaScript file loading/dependencies through the //= require xxx syntax. With Nodeify, your javascripts fit into the standard CommonJS modules framework. You can use var MyLib = require('./xxx') statements that are relative to your app/assets/javascripts directory. You can also use require() to load Node.js npm modules (see below).

Note that you cannot require anything outside of app/assets/javascripts. This is OK because anything that would go into lib/assets or vendor/assets should probably be its own npm module, anyway. At the very least you can dump extra libraries into app/assets/javascripts/lib and require them with var foo = require('lib/foo');.

Understanding require()

The CommonJS require() works a bit differently than Ruby's require or the sprockets //= require. CommonJS isolates modules (any code grouped into a file) into its own environment. Variables defined local to the module will only be available in that module. Here are a couple of quick examples:

// in app/assets/javascripts/lib/misc.js
exports.cool = function() {
  console.log('exports are cool');
};

// in app/assets/javascripts/my-class.js
var MyClass = function() { };
MyClass.prototype.cool = function() {
  console.log('prototypes are cool');
};
module.exports = MyClass;     // note that it's module.exports

// in app/assets/javascripts/application.js
var misc = require('./lib/misc'),
    MyClass = require('./my-class'),
    _ = require('underscore');  // this is an npm module

misc.cool();
var klass = new MyClass();
klass.cool();
_.each([1,2], function(i) { console.log(i); });

Node modules

In your app's root directory, add any npm module dependencies to package.json file, just like any Node.js server app or npm module. Nodeify will add a default package.json for you. Npm dependencies look like:

"dependencies": {
  "jquery-browserify": ">= 1.3.x",
  "jsonpath": "*"
},
"devDependencies": {
  "browserify": "*"
}

Once you've updated dependencies, you can install the newest modules with

$ npm install

Asset Pipeline Misc.

Nodeify integrates seamlessly with the standard asset pipeline workflow. The only difference is the use of CommonJS require() instead of sprockets' require.

Testing

Testing tasks are defined in the Cakefile, according to whether jasmine (default) or vows is selected as the testing framework. Run your JavaScript tests with cake test. Individual files can be tested with cake test -p spec/MyClassSpec.js (jasmine) or cake test -p test/my-class-test.js (vows).

Contributing to nodeify

Copyright

Copyright (c) 2011 Derek Kastner. See LICENSE.txt for further details.