Search code examples
javascriptnode.jsgruntjsnpmbrowserify

How to bundle multiple javascript libraries with browserify?


I'm trying to use Browerifiy in the browser, if I use the standalone option it exposes one module. I don't want to do this. The website and documentation just seems to cut off everywhere I look after actually compiling the code. No one has said how to actually use the code in the browser property.

I have a grunt task as such:

browserify: {
      standalone: {
        src: [ '<%= yeoman.server %>/shared-components/**/*.js' ],
        dest: '<%= yeoman.client %>/app/js/browserifed-shared-code.js',
        /* Commented out, zero documentation on this. Can only expose one module it seems.
        options: {
          browserifyOptions: {
            standalone: 'Utility' //Unable to say '**/*' error :-/
          }
        }
        */
      },

This seems to work, it makes a file like this:

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var UrlController = function(){};

UrlController.test = function () {
    return 'test';
};

module.exports = UrlController;

},{}],2:[function(require,module,exports){
'use strict';

var Utility = function(){};

Utility.isASCII = function (str) {
    return /^[\x00-\xFF]*$/.test(str);
};

Utility.isAlphaNumeric = function(str) {
    var code, i, len;
    for (i = 0, len = str.length; i < len; i++) {
        code = str.charCodeAt(i);
        if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
            return false;
        }
    }
    return true;
};

module.exports = Utility;

},{}]},{},[1,2]);

I include it automatically using an injector which works simular to:

<script src="app/js/browserifed-shared-code.js"></script>

Now i expect that I'd be able to call

require('Utility');

But I get

Uncaught ReferenceError: require is not defined(…)

I have no idea/no way of loading these modules in the browser. :'-/


Solution

  • You have two choices here. Either you

    SOLUTION 1

    Create a standalone browserify module for each library you want to access in your browser. This has been answered in your other post. Basically you do multiple browserify bundles.

    .

    browserify library1.js --standalone Library1 -o library1-bundle.js
    browserify library2.js --standalone Library2 -o library2-bundle.js
    browserify library3.js --standalone Library3 -o library3-bundle.js
    
     <script src="library1-bundle.js" type="text/javascript"/> 
     <script src="library2-bundle.js" type="text/javascript"/> 
     <script src="library3-bundle.js" type="text/javascript"/> 
    

    So, in your building tool you would have

    browserify: {
          library1 : {
            src: [ '<%= yeoman.server %>/shared-components/library1.js' ],
            dest: '<%= yeoman.client %>/app/js/library1-bundled.js',
            bundleOptions : { standalone : 'Library1' }
          },
          library2 : {
            src: [ '<%= yeoman.server %>/shared-components/library2.js' ],
            dest: '<%= yeoman.client %>/app/js/library2-bundled.js',
            bundleOptions : { standalone : 'Library2' }
          },
          library3 : {
            src: [ '<%= yeoman.server %>/shared-components/library3.js' ],
            dest: '<%= yeoman.client %>/app/js/library3-bundled.js',
            bundleOptions : { standalone : 'Library3' }
          }
    }
    

    SOLUTION 2

    Or, create a main entry point for all your modules.

    // ---- main.js -----
    module.exports.Library1 = require('./lib1');
    module.exports.Library2 = require('./lib2');
    module.exports.Library3 = require('./lib3');
    

    Then, you use browserify

    browserify main.js --standalone Library -o bundle.js
    

    Then in your browser

    <script src="bundle.js" type="text/javascript"/> 
    

    In your grunt task :

    browserify: {
          standalone: {
            src: [ '<%= yeoman.server %>/shared-components/main.js' ],
            dest: '<%= yeoman.client %>/app/js/main-bundled.js',
            bundleOptions : { standalone : 'Library' }
          }}
    

    Note on Module Loaders and Browserify

    Then, to expand on the answer I made on your previous post, browserify exposes it's bundled modules differently depending on the module manager present in your environment.

    • If you are in node, it's commonJS (sync) so you can use require('');
    • If you are using AMD (async), you can use that AMD syntax.
    • If you are in the browser, you muse use either window. or global.

    Grunt dynamic task definition

    To automate this a little, you can also pass in a configuration :

    bundledLibraries : [
        Library1 : {
            src : './../src/lib1.js',
            dest : './../src/lib1-bundled.js'
        },
        Library2 ...
    ]
    

    Then you iterate to add them to the grunt config (

    Check this article for creating them dynamically http://www.integralist.co.uk/posts/dynamic-grunt-tasks.html