Things like Gulp and Grunt are unnecessary extra tools that can be left to devs to use with their apps.
have the project build itself out of the box, but also easily integrate into other pipelines?
We should support the most common set of build systems without any extra layers (no gulp/grunt): Webpack+NPM, Browserify+NPM, JSPM (by Guy Bedford, who leads efforts on things like this), Bower+RequireJS (yes, we can! Bower still has 470,000 downloads per week), and a global build (that’s a build system for many people still ).
I’ve been thinking about how to be compatible with all those cases since when I started the infamous/infamous repo using Famous 0.3. Check out the package.json
over in https://github.com/infamous/motor/tree/joe.
The idea is fairly simple:
- package.json includes scripts to build to AMD, CJS, and UMD (assuming we’re writing in ES6).
- Source lives in the
src
folder.
- On
prepublish
to npmjs.com, files are built to CJS format into to root of the package, then published. Prepublish only uses the build-cjs script, and the other scripts are there in case someone wants to make use of them, for convenience (for example, someone might have a custom RequireJS workflow, and can use the build-amd script to get AMD files). The clean
script removes the build files after prepublish, or manually if needed (it takes a little extra effort to maintain these scripts as the code base changes, but I feel it’s worth it).
- The packages is published with both the build files in the root and the original files in the
src
folder to maximize coverage of use cases. Some people will require the root files directly, using Webpack or Browserify, or perhaps even natively in some Node.js-based GUI, or even on the serverside for testing or something (or if we one day support server-side rendering). The src
folder is intact so that people who use JSPM can set directories.lib = src
and JSPM will set that folder as the root of the package once installed. Other people might like to set an alias in Webpack to the src folder in order to use the original ES6 modules for some reason. Basically, let’s let people do what they want.
- The devDependencies include babelify in case someone configures browserify to use the src folder’s ES6 files instead of the CommonJS ones. No harm done including it.
- TODO: We need to precompile GLSL during prepublish. We can use either Webpack or Browserify for that with glslify or glslify-loader. @talves has thought about this. How can we inject the GLSL without modifying the rest of the code in the file where it is injected? Or might it not matter if Webpack is compiling, perhaps, a Broweserified/glslified file?
- There are some extra fields for
jspm
and bower
. Bower is todo.
- The babel-runtime package is a runtime dependency, which simply includes some function helpers like those used to create prototype-based classes in ES5, etc. The
--optional runtime
option in the build-* scripts tells babel not to include these helper functions in each and every file, instead using require
to get the helpers. It’s a good thing to have the runtime.
- The
format
property helps some build systems. F.e., JSPM doesn’t have to make a guess.
- The browser, main, and global fields help in some cases.
Basically, the idea was to maximize coverage of the most notable use cases. Not necessary, but I’ve also included a Meteor package to make it easy for Meteor users with no module experience to consume it. I wrote that fast, I feel like it was sloppy. x}