Entering into using Browserify for the first time demands an answer to an important question — What is Browserify?
Browserify simplifies dependencies management and usage of your Javascript application by utilizing commonJS import formats (require('modules')
) and bundling them with your app for deployment. It’s kind of funky to say, and yes several times I referenced it as browserfy, omitting the i. There are other similar products (RequireJS), but this utilizes the node module syntax of module.exports
instead of using AMD.
How do I Browserify?
The easiest way to get started is to follow the tutorial on their website. First, install using npm:
npm install -g browserify
Require-ing Dependencies
How browserify looks for required modules:
require('bar')
– will look in your node_modules directoryrequire('./bar')
– will look in the current directoryrequire('../plugins/bar')
– will look in the relative path
Note: If you are migrating to using Browserify from another mechanism, you may want to use node to manage these dependencies. For example, instead of storing a versioned jquery library in your repository, you can update your package.json to include “jquery” : “2.1.1” as a dependency. It will then install in the node_modules directory when you run npm install
.
Browserify and ReactJS
For our use case, we intend to utilize Browserify within a ReactJS application. Our usage of React kept classes isolated in JSX files, and compiled and used in the UX. Here is an example of a class:
define(["react"], function (React) { return React.createClass({ //************ Meta Data **************// displayName: "MessageDisplay", propTypes: { message: React.PropTypes.string.isRequired, }, //************ Render **************// /** * Render the loading component. * * @return {object} */ render: function () { return ( <main className={"container message-display"}> <p>{this.props.message}</p> </main> ); }, }); });
And used by:
define(["react", "component/MessageDisplay"], function (React, MessageDisplay) { React.renderComponent( MessageDisplay({ message: "Welcome back!" }), document.getElementById("box") ); });
Now, the class is add to the module.exports:
var React = require("react"); module.exports = React.createClass({ //************ Meta Data **************// displayName: "MessageDisplay", propTypes: { message: React.PropTypes.string.isRequired, }, //************ Render **************// /** * Render the loading component. * * @return {object} */ render: function () { return ( <main className={"container message-display"}> <p>{this.props.message}</p> </main> ); }, });
and used by:
(function () { var React = require("react"); var MessageDisplay = require("./components/MessageDisplay"); React.renderComponent( MessageDisplay({ message: "Welcome Back!" }), document.getElementById("box") ); })();
Grunt integration
To integrate Grunt with Browserify, include the grunt-browserify plugin in your package.json, and update your Gruntfile.js with:
browserify: { dist: { files: { // all files to put into the bundle 'bundle.js': ['<%= config.app %>/js/main.js'], }, options: { // options passed to browserify browserifyOptions : { debug: true // create source maps } } } }eibcccunbgvtkefgrgdlbvkrlebdvbeghfljllflgfie eibcccunbgvtjgcbuhivrldjktdckbjvibnikcdvgudf
The plugin will pull all required files as well, so you don’t need to specify them all if you have only a single access point to your application. If you have multiple pages with varying content, you can create multiple output files and include each unique bundle (“account-bundle.js”, “help-bundle.js”, “game-bundle.js”, etc.).
I’ve also included the options for generating source maps, which map the lines within the compiled code to the original file and line, invaluable when trying to hunt down a bug!