documentcloud/underscore — pull request #817 by jakesandlund (2012-10-08 00:00:20+00:00)
Title: Node modules in the browser (adds only 343 bytes)

This pull request splits underscore into separate node modules, adding only 343 bytes (7.4%) to the minified and gzipped file. Most of the size comes from converting to a node format; the script to make it work in the browser is only 109 of those bytes. That's less than the [copyright comment header](https://github.com/documentcloud/underscore/blob/29e1ba38f6d16b17e4b6b7805be8e1be2d27cb83/underscore-min.js) (112 bytes).

*How does it work?*

I used [vaccine](https://github.com/jakesandlund/vaccine): a way to get modular JavaScript in the browser that is small enough that libraries (such as this one) can use it. Applications (or [other libraries](https://github.com/documentcloud/backbone)) using vaccine can now `require('underscore')`. That said, no one is forced to use vaccine, because it is included with the underscore sources. Note that since the modules are in node format, they get used directly in Node.js.

*Doesn't this add a build step, so I can't just refresh?*

Yes and No.

Yes, you do need to build. If underscore was only used in the browser, the [build](https://github.com/jakesandlund/vaccine/blob/master/build) step could have been as simple as wrapping the concatenated sources in `(function() { ... }());`. Underscore's build script does a bit more to wrap the node modules in `define` calls.

No, you don't have to manually build every time. A small development server (performing the node `define` wrap) makes it so a simple reload is all that's needed. Along with that, I added a [script loader](https://github.com/jakesandlund/vaccine/blob/master/vaccine_loader_simple.js) that can load files whenever there is a `require()`.

*How is it so small?*

Vaccine keeps a [minimal](https://github.com/jakesandlund/vaccine/blob/master/vaccine_minimal.js) global API constant while varying `define` and `require` functionality (which is local to the app/lib) to suit different needs. In underscore's case, it makes sense to use the [vaccine_simple.js](https://github.com/jakesandlund/vaccine/blob/master/vaccine_simple.js) implementation, as the more advanced features are not necessary. Take a look at the [README](https://github.com/jakesandlund/vaccine#vaccine) for more information.

Lastly, converting to a modular format required decisions that are not mine to make. I hope that any controversial choices I made won't stop you from seeing the "big picture" advantage of modular JavaScript in the browser for a very small size cost.