Wednesday, May 19, 2010

Using RequireJS syntax in Jetpack Reboot

I have a clone of the Jetpack SDK that has support for the require() and require.def() syntax supported by RequireJS.

Right now the syntax support is very basic. It does not support these features of RequireJS:
  • configuring require() by passing in a config object to it
  • plugins
  • require.modify
  • require.nameToUrl
  • require.ready (does not make sense)
But you can do the main things, like:

require(["dependency"], function (dependency){}());

and define modules via:

require.def("moduleName", ["dependency"], function (dependency){}());

It should also support CommonJS modules that were converted to RequireJS syntax via the conversion tool in RequireJS, but I have not tested it extensively.

The changes are just in one file in the sdk, securable-module.js. So you could just grab that file if you wanted to play with it. There is a sample app in the source if you want to see it in action. Also viewing the changeset shows the diff on the securable-module.js file as well as the example app source.

The full cloned repo is available via:

hg clone http://hg.mozilla.org/users/jrburke_gmail.com/jetpack-sdk-requirejs

Why do this? Because sharing code between the browser and other environments is hard with the regular CommonJS syntax. It does not work well in the browser. The browser-based CommonJS loaders that use eval() have a worse debugging experience. Starting with the RequireJS syntax makes it easy to transfer the modules for use in the web browser, and the RequireJS code works in Node and Rhino.

I would like to add support for RequireJS plugins in Jetpack. I can see the i18n plugin and text file plugin being useful for Jetpacks. That will likely take more work though. I want to see if the basic syntax support is useful first.

I ended up not using that much RequireJS code, just some argument conversions and supporting "setting the exported value". It relies on the existing Jetpack code for paths and package support.

Sunday, May 16, 2010

RequireJS 0.11.0 Released

RequireJS 0.11.0 is available to download! This release has the following enhancements:
Thanks to Alex Sexton for outlining the Caja and require() renaming aspects and to Sean J. Vaughan for instigating the JSONP plugin.

The priority config option is the parallel download support I mentioned in the "A require() for jQuery" post. I now believe RequireJS meets all the requirements outlined in that post.

Some icing on the cake I want to pursue: a server-based service that can create optimization layers on the fly. I have all the pieces in place in the optimization tool to allow this, and I previously built a server build option for Dojo. With that, you could conceivably use the priority config support with a server that did the optimization layers on the fly:
require({
priority: [
"http://your.domain.com/opt?include=event,object,widget,Dialog&exclude=jquery",
"http://your.domain.com/opt?include=page1,Tabs&exclude=jquery,event,object,widget,Dialog&exclude=jquery"
]
}, ["page1"]);
Or something like that. The fun part -- this server endpoint would use server-side JavaScript, since the optimization tool in RequireJS is built in JavaScript. I could use Node or something Rhino-based. It is likely to be Rhino-based since that allows the minifier, Closure Compiler, to work on the fly, since Closure Compiler is written in Java.

That server-based service will likely take a more design work and thought, but if you feel it is something necessary for your project, please let me know. Better yet, if you want to contribute to the project in this area, leave a note on the mailing list.