The RequireJS project has a script called r.js which will “compile” a set of AMD modules into a single file. There are other projects like Browserify which do the same thing for a collection of CommonJS modules Basically, all of these figure out the ordering from the dependencies, concatenate the files, and inject a minimalistic bootstrapper to provide the require/module/exports functions. Unfortunately, this means that they all have the downside of leaving all the ‘cruft’ of the module specification in the resulting file.
1 2 3
1 2 3 4
When I run this through browserify, it produces this output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
When you run the resulting program in either a browser or nodejs, it does the right thing and tells you 75. But look at how much garbage there is! To deal with the require & module parts, it defines a bunch of stuff at the top, seriously bloating the file. The original program code was 9 lines of code with 169 characters). The “compiled” version was 14 lines and 733 characters. Minifying it with uglifyjs only shrinks it down to 713 characters.
In an ideal world, I would like system that can produce this from those same three source files:
1 2 3 4 5 6 7 8 9
That looks better to me and is only 114 characters long (minified it is 95). Because I used the module pattern, like the compiled version, it doesn’t leak anything into the global namespace.
I found a number of other tools for doing single-file compiles, but none of them seemed to take the kind of aggressive approach to optimization that I think would be ideal when building a large library, so for now I’ve been using a hacked up version of the JQuery build system.
Next up, I’m going to look at what I can get from TypeScript modules. Maybe it will give me more of what I want.