Monday, May 28, 2012

RequireJS 2.0 released, onward AMD

RequireJS 2.0 is available.

There is an in-depth upgrade guide to what is new, but the big ideas behind the release:
While the 2.0 code has gotten some use, it is still new, and it is naturally more subject to issues than the 1.0.x releases. If you do see an issue, please report it.

I am really grateful for the quality and quantity of community feedback that prompted the 2.0 release, with community members paving the way for core changes by doing implementations via the loader plugin API.

Plugin APIs are awesome, and the loader plugin API is one of the great strengths of the AMD module ecosystem. In addition to reducing the "pyramid of doom" that can occur in async resource fetching, it helps try out ideas for the loader, and supports transpiled languages like CoffeeScript.

I sometimes see some confusion about AMD modules and RequireJS, and I want to take a moment to reiterate the problem they are trying to solve.

The AMD API is about getting workable module syntax in JavaScript that meets all the async, networked nature of browsers without having the hidden costs down the road (no eval, CORS/cross-origin concerns, needing a transform to ship code).

Node's module API and using something like browserify is not enough for browser modules. It works for a certain case of problems, but to be a complete solution, a standardized callback-based require for on-demand async loading after initial module load and a wrapped module format that supports named modules for bundling are needed at a minimum. Loader plugins are also incredibly useful for reducing the async "pyramid of doom" for resources that are needed as part of module initialization. If node was able to integrate something like amdefine into their core it would really make it a complete JS module solution.

ECMAScript harmony modules account for the async network IO in browsers, and it has the ability to change the internals of browser script loading so that it will not hit the eval and CORS issues that node/commonjs modules have. But it is not done, and still has quite a few kinks to work out. It will still have the same "how do I use browser globals scripts that do not declare their dependencies" issues that people see when starting to use AMD modules with older scripts. The shim config in RequireJS 2.0 is an attempt to ease that problem, and I hope that AMD and RequireJS can continue to help inform the ECMAScript effort.

So until node closes the gap on some things needed for browser loading, or ECMAScript harmony modules work out the kinks and ship, there is AMD, and RequireJS aims to be the reference implementation for the AMD APIs.

If you want to support AMD loaders in your library code, there are some code templates that can help you do that in a way that still allows your code to work in traditional "browser globals" situations.

AMD: the worse JS module API, except for all the others. Because it works better in more cases.


Jason Diamond said...

Thanks James. Really appreciate your work on this.

Jordan said...

Awesome! Thanks James.