Browserify: Use module.exports if required, otherwise expose global

32,093

Solution 1

There is a good article from Forbes Lindesay explaining how to do standalone builds: http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds

The short version, use the standalone option:

browserify beep.js --standalone beep-boop > bundle.js

Solution 2

I'm dealing with the same problem building a library and here is a rought opinion. I think we need to separate first the audiences for a library in few categories:

  1. those who use browserify and NPM
  2. those who will just download a mylib.min.js and use one way or another
  3. AMD (with bower?), might be the third category.

So, for 1 it is easy, you will have a your index.js module:

module.exports = function () { /* code */ }

and your package.json will have a main

"main": "index.js"

Notice I haven't add any window.xx code to index.js.

For 2 I think the best idea is to create a standalone.js

var mylib = require('./index.js');
global.window.mylib = mylib;

This is what browserify should build.

For 3 (if you care about) you can tweak standalone.js as follows:

var mylib = require('./index.js');
if (typeof global.window.define == 'function' && global.window.define.amd) {
  global.window.define('mylib', function () { return mylib; });
} else {
  global.window.mylib = mylib;
}

Solution 3

Assuming another library hasn't created a global module.exports object, you can simply check for the existence of module.exports

var mymodule = (function() { ... })();
if (module && module.exports) {
  module.exports = mymodule;
} else {
  window.mymodule = mymodule;
}
Share:
32,093
Bryan Head
Author by

Bryan Head

I'm a PhD student in Computer Science at Northwestern. I work on all thing NetLogo.

Updated on June 26, 2020

Comments

  • Bryan Head
    Bryan Head about 4 years

    I'm considering adopting browserify for some of my projects, but would like to make sure that others don't have to use browserify if they want to use the (bundled) code. The obvious way to do this is to both expose the modules exports through module.exports as well as through a window. global. However, I'd rather not pollute the global namespace for those who are requireing the script.

    Is it possible to detect if a script is being required? If it is, then I could do something like:

    var mymodule = (function() { ... })();
    if (isRequired()) {
      module.exports = mymodule;
    } else {
      window.mymodule = mymodule;
    }
    

    Note that no matter what, this will be bundled beforehand, so the var mymodule won't be exposing a global. Also, currently I'm using the revealing module pattern, but would be willing to switch to something more appropriate for browserify.

    What's the best way to make a module both requireable and <script src=able? Is it best to just expose a global in both circumstances?

  • Bryan Head
    Bryan Head about 11 years
    Browserify make module, module.exports, and require available to all bundled files. So, just my bundling makes those available. Thanks for the response.
  • Trevor
    Trevor about 6 years
    Link uses deprecated code. Can't pass options to bundle() anymore. Also link doesn't explain where it got beep-boop from and if the name is significant, and what to replace it with in the real world.
  • Duncan
    Duncan over 5 years
    Isn't "global" the same as "window"? If so, shouldn't it be "global.mylib = mylib" rather than "global.window.mylib = ..."?
  • parttimeturtle
    parttimeturtle almost 4 years
    I'm not sure of the correct terminology but "beep-boop" in this example is the 'namespace' you want to contain the standalone functions within. So if I browserify'd a function byteLength (...){...} with browserify infile --standalone myspace -o outfile, I would access the function by calling myspace.byteLength(...) from within the JS file that has included outfile via require().
  • KellyCode
    KellyCode over 3 years
    Just to clarify; Using browserify version 17.0.0 with the above gives me the working bundle and correctly exposes a camel cased global 'beepBoop".