0

Have successfully bundled a module collection of Javascript classes into a single library using browserify. But I need to define _ and Backbone as global modules and wonder if that's the best way.

MyLib is mostly a Backbone collection which requires other submodules:

var _ = require('lodash');
var Backbone = require('backbone');
if (typeof window !== 'undefined') Backbone.$ = window.$;

var foo = require('foo'), bar = require('bar');
module.exports = Backbone.Collection.extend({ ... my library... });

Because Backbone and Underscore are bigger and more general, would like not to bundle them but treat them as external dependencies. So in package.json, am using browserify-shim to exclude them:

...
"browserify": {
    "transform": [
      "browserify-shim"
    ]
  },
  "browserify-shim": {
    "lodash": "global:_",
    "backbone": "global:Backbone"
  }

The module loads fine in the browser, as _ gets defined as global variables:

  <script src="/javascripts/underscore.js"></script>
  <script src="/javascripts/mylib.js"></script>

  <script type="text/javascript">
    console.log(new MyLib()); // loads fine standalone or via require.js
  </script>

But in Node.js, the browserify-bundled module looks for these external dependencies in an object called global

  var _  = require("lodash");
  var MyLib = require("./libs/mylib");

This fails with TypeError: Cannot call method 'isEqual' of undefined because _ is undefined. Inside mylib.js at the top I see the line:

var _ = (typeof window !== "undefined" ? window._ : typeof global !== "undefined" ? global._ : null)

However, I can get it to work by defining the dependencies globally like so:

  var _  = GLOBAL.global._ = require("lodash");
  var MyLib = require("./libs/mylib");

But this creates global variables, which many strongly discourage in this post: node.js global variables?

Is there a better way to include external dependencies for Browerify modules in Node.js?

How do I use Browserify with external dependencies?

Community
  • 1
  • 1
prototype
  • 7,249
  • 15
  • 60
  • 94
  • 1
    you use it by writing your code for "not the browser", e.g. in your `mylib` you'd import underscore as `_ = require('underscore')` instead of relying on `_` to exist as magical global variable. Browserify will then generate a for-the-browser bundle that will simply make that require work. To give a better answer, we'll need to see what `MyLib` looks like (ideally, reduced so that the bulk of "just API" is omitted) – Mike 'Pomax' Kamermans Mar 17 '15 at 23:34
  • Am including them via `_ = require('underscore')` but not bundling them by excluding them with browserify-shim. It dawns on me slowly that browserify handles this in Node by explicitly requiring them them to be global variables, just like require.js shims do in the browser. So maybe defining _ as a global variable is just the cost of not bundling it in my lib. – prototype Mar 18 '15 at 03:00
  • I assume you're not bundling it in because you already have `_` loaded separately in the browser then, in which case probably want to use `browserify-global-shim` instead of `browserify-shim`, which lets you replace module requirements in the original source to "just using the global" in the bundled code. – Mike 'Pomax' Kamermans Mar 18 '15 at 16:10

0 Answers0