at

Basic features

  • resolves and deduplicates requite statements across modules
  • encapsulates each module and entire bundles to isolate objects

Alternatives

  • Webpack
  • rollup

browserify & commonjs ecosystem advantages

  • stable, most popular bundler
  • robust ecosystem https://github.com/substack/node-browserify/wiki/list-of-transforms (214 transform packages tagged on npm)
  • modular plugin system provides easier setup and matches all features of alternatives with compatible plugins like rollupify
  • commonjs availability on server via node.js and on client via browserify allows modules to run in either environment

npm usage is massive

npm has a lot of packages

bundle file

The bundle is the starting point, can require local files, npm modules or local modules

// 3rd party code we got from icomoon to cache svg icons
require('app-svg-cache');

// local modules
var smartBanner = require('app-smart-banner')();
var zipAutoComplete = require('app-autocomplete')();
var smartBanner = require('app-smart-banner')();
var saveHandler = require('app-save-home-icon')();

// local module required
var searchFilter = require('app-filters')
// the only instantiated if needed on the page
if(document.querySelector('#searchBtn')) {
  var searchFilterOverlay = new searchFilter();
}



  • command line
  • grunt-browserify
  • gult-browserify
  • npm scripts

bundling options

Our Grunt task

// used grunt-browserify
// references bundle file and output file
browserify: {
  global: {
    files: {
      "../../js/modules/global.js": "ui-module-bundles/global.js"
    }
  }
}
// after this we run the generated file through minification, etc.

browserify transform options we use

  • Handlebars precompilation
  • ES6 transpilation
  • CSS insertion

Template precompilation

The package.json associated with any module requiring template precompilation uses the hbsfy transform then the template is precompiled during the browserify grunt task and the minimal handlebars runtime is included in the bundled .js file

  "browserify": {
    "transform": [
      [
        "hbsfy",
        {
          "extensions": [
            "html"
          ],
          "precompilerOptions": {
            "knownHelpersOnly": true,
            "knownHelpers": {
              "ifequal": true,
              "mlsresult": true
            }
          }
        }
      ]
    ]
  },
npm install hbsfy --save-dev

ES6 transpilation

We use ES6 features like maps, sometimes ES6 templates. If your module needs features like this add the babelify transform to the package.json and install the required npm packages

  "browserify": {
    "transform": [
      [
        "babelify",
        {
          "presets": [
            "es2015"
          ]
        }
      ]
    ]
  },
npm install babelify --save-dev
npm install babel-preset-es2015 --save-dev

CSS insertion

We've experimented with bundling CSS with our module, hoping to have a fully encapsulated UI unit. Doing this will make the module js insert the CSS block into the page. It requires the transform npm install, the transform definition in the module package.json and the css insertion line in the module code.

  "browserify": {
    "transform": [
      "browserify-css"
    ]
  },
var css = require('./index.css');
npm install browserify-css --save-dev

Creating a new module

  • Create new directory
  • Build package.json accepting default options
mkdir app-zipMenu
cd app-zipMenu
npm init -y
npm install ./app-zipMenu --save-dev

Run the npm install command to add you new module to the main package.json so other developers can install it

var $ = require('jquery');

module.exports = zipMenu;

function zipMenu() {
  if (!(this instanceof zipMenu)) return new zipMenu();
  // do some stuff
};

module code

Audit modules with npm-check

  • Check to make sure all modules are using desired version of dependencies
  • Checks for unused dependencies

Deployment

  •   we checkin only the js we have written, the package.json for our modules and the generated bundles
  • The node_modules folder inside each of our modules is gitignored.
  • This lets us check in less code, deployment is faster and less error prone because no npm installs are performed during that process, bundles are only created when code is changed
  • sourcemaps give us visibility into unminified code in all environments
  • we do run into git merge conflicts with the generated files which we solve by just rerunning the grunt tasks

Transition

  • We are in the middle of a gradual switch from plain script tags with all code based on YUI
  • The encapsulation provided by browserify makes it safer for us to replace legacy code bit by bit and run our new bundle along with legacy js includes
  • Splitting separate components into different modules has allowed us to refactor bits of the new codebase with less side effects
  • We write a log of local modules using the app- prefix

More information

browserify at ziprealty

By Aaron Hans

browserify at ziprealty

  • 729