Wednesday, January 27, 2010

RunJS to RequireJS?

There was a thread that started on the CommonJS list about a transport format, something that works well in the browser via script injection. I sketched out a proposal, Transport/C, that builds on the Transport/B and Transport/A specs.

Transport/C is very similar to some basic mechanics of RunJS but uses require() as the top level function, and supports the special "module" and "exports" free variables used in the normal CommonJS module spec.

In order to prove the concept for Transport/C, I made a branch of the RunJS code, calling it RequireJS, that implements Transport/C.

It seems like it fits with the existing CommonJS module spec, but is something that works well in the browser. I also made a simple conversion script that converts traditional CommonJS modules to this format.

I am tempted to convert from RunJS to this RequireJS branch, and to start evangelizing that approach for browser toolkits. It would be great if Transport/C would also be approved as the transport format for CommonJS too.

Kris Kowal has some concerns about the *very* long-term effects of the approach. I read his comments as possibly pointing out some things that would be done differently if the primordials and e-maker type of modules were ever accepted as part of an ECMAScript standard.

As I read the primordials and e-maker strawman proposals, I think the only difference is Transport/C functions are only expected to be called once, but e-maker style would favor calling the function on every require() call. As I say in my response, I believe e-maker support, would affect regular CommonJS modules in the same way as the transport format, and it is assuming the strawmans make it in to the spec at some point, as they are specified now.

I also believe how it works in how I coded Transport/C as part of the RequireJS branch is what a normal developer would expect, and I think fits better with existing browser/script behavior, and the assumptions that go along with coding CommonJS modules today.

So I am tempted to rename the RunJS project to RequireJS and proceed with that. If you have any feedback to the contrary, please let me know. Otherwise, I will likely do the change early this week.


Bill Keese said...

I agree (I tried to post a response on the CommonJS thread too).

eMaker is interesting but it seems too restrictive, and as you suggested the same thing can be achieved by just defining a function that returns an "eMaker" function.

Kris Kowal said...

The proposal I'm making to ECMA would support both e-maker and require. The "load(id)(scope)" approach would load an emaker injecting the given object as the named arguments to the maker function. Thus e-makers would be multiply instantiable and support domain specific languages that depend on additional free variables, like Jakefiles, QUnit scripts, and the like without having to communicate with global variables. The "require(id)" system would be built upon that. I think these approaches need to be separate or separable.

James Burke said...

Kris Kowal: thanks for the clarification. As for the free variables, I do not see a way to generically support them for a transport format.

I posted to the CommonJS group about that issue. If you have any insights on how to do that for a transport format, it would be great to know.