Modular js in Rails

Sprockets - rails assets pipeline

  • manifests files compiled for production

  • require order is important 

app.doSomething2 = function () {
    ...
    app.doSomething1();
}
app.doSomething1();
app.doSomething2();
app.doSomething1 = function () {
    ...
}

do_something1.js

do_something2.js

app.js

// = require jquery
// = require jquery_ujs
// = require_tree .

application.js

... undefined method

doSomething1 :(

// = require jquery
// = require jquery_ujs
// = require do_something
// = require do_something2
// = require app
//= require planner_creator/main
//= require ./lib/rich-marker
//= require_tree ./planner_creator/templates/
//= require ./planner_creator/routers/application_router
//= require ./planner_creator/models/planner
//= require ./planner_creator/models/activity
//= require ./planner_creator/models/poi
//= require_tree ./planner_creator/views/app
//= require ./planner_creator/views/map_region_view
//= require ./planner_creator/views/application_view
//= require ./planner_creator/views/creator_view
//= require ./planner_creator/views/map_range_view
//= require ./planner_creator/views/map_view
//= require ./planner_creator/views/new_planner_view
//= require ./planner_creator/views/poi/activity_select_view
//= require ./planner_creator/views/poi/load_global_poi_view
//= require ./planner_creator/views/poi/poi_index_view
//= require ./planner_creator/views/poi/poi_item_view
//= require ./planner_creator/views/poi/poi_form_view
//= require ./planner_creator/views/choose_region_form_view
//= require ./planner_creator/views/choose_range_form_view

Require.js

AMD pattern

Useless with rails asset pipeline :(

Require.js

  • Loads scripts asynchronously only when they are needed
  • Scripts can be bundled to one file but after complex configuration

Sprockets

  • Compiles all scripts to one file for production
  • Scripts evaluated on load time
  • require order is important 

Modulejs

Modular desgin with compiled scripts

modulejs.define('wheel', function () {
    return {
        rotate: function() {
        }
    };
});

Single module definition

modulejs.define('car', ['wheel'], function (wheel) {
    var car = {};
    wheel.rotate();
    // ...
    return car;
});

Module with dependency

var car = modulejs.require('car');

Main script

 

// = require jquery
// = require jquery_ujs
// = require_tree .

application.js

  • Single require_tree in manifest
  • Intuitive script/file separation
  • We can skip paloma gem
modulejs.define('welcomeController', function () {
    return {
        index: function() {
            ...
        },
        show: function() {
            ...
        }
    };
});
:javascript
    $(document).ready(function(){
        var controller = modulejs.require('welcomeController');
        welcomeController.index();
    });

welcome_controller.js

index.html.haml

Made with Slides.com