Easily Bundle Common Modules (grunt-browserify) by Will Acton / 15 July 2015

Here's an easy way to bundle up common libraries used in a project into a single file, without requiring a bunch of extra plugins.

Looking at the npm/grunt/browserify ecosystem, it's not too hard to make your head spin with all of the plugins and tools people have developed. Previously, grunt-browserify was all I was using to bundle up my files, and the less complexity my build step has, the better.

I tried browserify-shim, factor-bundle, exposify, and numerous combinations of different config options trying to get it right. But which options go in grunt-browserify's config, as opposed to browserify-shim's transform config? Or should it all be in package.json??? All I want is React and react-router in their own file! Ahhhhh!!!

Finally I ran across this blog post which has an interesting, undocumented feature of grunt-browserify:

The bundle.require() API is exposed through grunt-browserify's "alias" configuration.

It turns out, we can do something like this in our grunt-browserify config:

libs: {  
    // External modules that don't need to be constantly re-compiled
    src: ['.'],
    dest: 'dist/js/libs.js',
    options: {
      alias: [ // modules we want to require and export

The colons are added to the end of the module names due to the syntax of browserify's require parameter.

We can run grunt browserify:libs to bundle our libs up, and include the dist/js/libs.js in our .html file where our code will live.

Now in our application grunt-browserify config, we can configure it like so:

dist: {  
    src: ['src/js/init.js'],
    dest: 'dist/js/app.js',
    options: { 
        // don't bundle these into app.js
        // expect these in a separate bundle
        external: ['react', 'react-router'],
        //... more config here like transforms, etc.

VoilĂ ! Now we can separate our libraries and external modules from our application code, and it didn't require us to manage 4 different plugins and tools to do so!