Build CommonJS modules for the browser via a chainable API
Switch branches/tags
Nothing to show
Pull request Compare This branch is 64 commits behind mixu:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

gluejs - features

  • Build scripts are written directly in Node, allowing for more optimized builds
  • lightweight, uses same require() implementation as browserbuild
  • render() to console, or directly to a HTTP request
  • include() any files or directories and blacklist by regexp using exclude()
  • replace() any library with one that gets looked up from under window.* (e.g. require('jquery') => window.$)
  • watch() the build and get notified when files in it change
  • define() any dependency as a block of code that you generate (e.g. for creating builds that export a subset of functionality)
  • concat() multiple packages into one build (e.g. where your final build consists of multiple files)
  • TODO npm() build from a package.json and apply .npmignore


Usage (http server)

new Glue()
    'jquery': 'window.$',
    'Chat': 'window.Chat'
  .render(function (err, txt) {
    res.setHeader('content-type', 'application/javascript');

Usage (file)

new Glue()
  .exclude(new RegExp('.+\.test\.js'))
  .replace('debug', function(name) {
    console.log('name', arguments);
  .watch(function (err, txt) {
    fs.writeFile('./core.js', txt);

Including files / directories, excluding by regexp

include(path): If the path is a file, include it. If the path is a directory, include all files in it recursively.

exclude(regexp): excludes all files matching the regexp from the build. Evaluated just before rendering the build so it applies to all files.

Setting default values

  reqpath: '/path/to/first/module/to/require/glue', // all relative paths are relative to this
  basepath: '', // strip this string from each path (e.g. /foo/bar/baz.js with '/foo' becomes 'bar/baz.js')
  main: 'index.js', // main file, preset default is index.js
  export: '', // name for the variable under window to which the package is exported
  replace: { 'jquery': 'window.$' } // require('jquery') should return window.$


.export(name): sets the export name (e.g. export('Foo') => window.Foo = require('index.js'); )

.render(function(err, text){ ...}): renders the result

Replacing and defining code

replace(module, code): Meant for replacing a module with a single variable or expression. Examples:

.replace('jquery', 'window.$'); // require('jquery') will return the value of window.$
.replace('debug', function debug() { return debug() }); // code is converted to string

define(module, code): Meant for writing a full module. The difference here is that while replace() code is not wrapped in a closure while define() code is.

.define('index.js', [ 'module.exports = {',
  [ (hasBrowser ? "  browser: require('./backends/browser_console.js')" : undefined ),
    (hasLocalStorage ? "  localstorage: require('./backends/browser_localstorage.js')" : undefined )
  ].filter(function(v) { return !!v; }).join(',\n'),

The example above generates a index.js file depending on hasBrowser and hasLocalStorage.

Concatenating multiple builds

Glue.concat([ package, package ], function(err, txt)). For example:

var packageA = new Glue()
var packageB = new Glue()

Glue.concat([packageA, packageB], function(err, txt) {

Watching a single build

.watch(function(err, text){ ...})

Renders the result and adds file watchers on the dependent files.

When the file changes, the callback will be called again, with the newly rendered version.

Note that this API is a bit clunky:

  • there is no way to unwatch a file other than terminate the program
  • on each watched file change, a console.log() message is shown
  • the API uses fs.watchFile(), so you do not get notification of newly added files in directories; watches are registered on the files that were used on the first render

But it works fine for automatically rebuilding e.g. in dev.


.npm(file.json): includes a package.json