bldr - a module builder for node.js and the browser
- You want to share code between node.js and the browser
- You do not want a build step between saving a file and running the code (in the browser, or on node).
- You want to be able to package your code for the browser in production.
- You want explicit control over what gets packaged.
bldr is a node.js package that builds a package for the browser, but still uses code that works
well from node.js. It does not try to infer your intentions from your require statements, but it adds
an api on top of require so that your intentions are made explicit.
With bldr, the code you write runs directly from node. In the browser during development, the code runs
through a simple transform (available as an express route handler). In the browser for production,
bldr will package your code into one or more files.
It has the following api:
- bldr.require: Require this file for both node and the browser.
- bldr.define: Define this file into your app's namespace for both node and the browser.
- bldr.browser: Add this file to the list for the browser.
Example
app/index.js
app/browser.init.js
app/models/index.js
app/models/User.js
app/views/Login.js
var bldr = require('bldr')('myapp', __filename, {appDir: '.'});
bldr.browser('/node_modules/underscore/underscore.js');
bldr.define('./models/User');
require('./views');
bldr.browser('./browser.init');
module.exports = function() {};
var bldr = require('bldr')('myapp', __filename, {appDir: '..'});
global.React = require('react');
bldr.browser('/vendor/js/react.js');
var React = require('react');
bldr.define('./Login');
module.exports = function() {};
var view = new myapp.views.Login();
document.getElementById('#app').innerHTML(view.render());
var User = require('../../lib/models/User');
describe('User', function() {
it('should be defined', function() {
expect(User).to.exist;
});
});
require('../../lib/views');
describe('Login View', function() {
it('should be defined', function() {
expect(React).to.exist;
expect(myapp.views.Login).to.exist;
});
});
if (process.env.NODE_ENV !== 'production') {
bldr.installExpress(server, {rootDir: __dirname, app: '/js/app.js'});
}
$ bldr package myapp app::www/app.js
$ bldr package myapp app::www/app.js app/admin::www/admin.js
FAQ:
require shim?
No require shim in the compiled file. lightest weight, simplest result.
This requires a specific loader?
The shim file implements a loader for dev purposes. In production you control your own loading.
How do I split my app into multiple files
The command line tool takes a list of 'require path'::'file to write'. It will go through the list in order, and first require the path, and then write out the state of the app (either into a shim loader with build
, or a concatenated file with package
). The next file to be required will only add any files that were not in the first package. In that way you can split the app however you want.
Say for example you wanted to have most of the dependencies in one file, and the app in another. You could have a lib/deps.js
file that would contain bldr.browser('path/to/underscore.js'); bldr.browser('path/to/backbone.js');
. lib/index.js
would then contain require('./deps.js'); bldr.define('models');
. Then the following command would put everything required by deps.js into the first file, and everything else into the second.
bldr package myapp lib/deps::www/js/deps.js lib::www/js/app.js
Is there a watch mode?
With the express module, the newest version the files will be served up during development.
There is support for generating a depenency file that make
will understand with the option --deps
. More build tool integration hopefully coming.