medikoo/modules-webmake — Issue #7: Code Splitting
Author: sokra
Created: 2012-02-23 17:06:56+00:00
State: open

GWT has a cool feature named [Code Splitting](http://code.google.com/p/google-web-toolkit/wiki/CodeSplitting) which loads parts of the code on demand. This is also appliable for webmake.

Here my idea:

``` javascript
// a.js:
var b = require("b");
// ...
bindEventHandlerForSomeRarEvent(function() {
// the magic keyword, which behaves normally in node.js
// but so some special thing in webmake
process.nextTick(function(err) {
// Some code loading err handler
// err is undefined in node.js
if(err) { /* ... */ }
var c = require("c"); // really big libary, which is only needed in this rar case
// ...
});
});
```

webmake core would provide the magic `process.nextTick` function to the compiled code.
`process.nextTick` do this in the compiled code:

* store the callback function
* adds a script tag to the document
* the script contains JSONP
* callback function (JSONP) adds some new modules to the context
* and calls the stored callback function.
* in case of an error (ex. timeout) the stored callback function is called with some kind of error parameter

Here is a quick hint on the compiled files:

``` javascript
// output.js
( /* core code */
({
"a": function(/* ... */, process) {
// a.js:
var b = require("b");
// ...
bindEventHandlerForSomeRarEvent(function() {
// the magic keyword, which behaves normally in node.js
// but so some special thing in webmake
process.nextTick(function(err) {
// Some code loading err handler
// err is undefined in node.js
if(err) { /* ... */ }
var c = require("c"); // really big libary,
// which is only needed in this rar case
// ...
});
});
},
"b": function /* content of b.js */
// here is no "c": !!
// which saves bandwidth
```

``` javascript
// may be named "a.output.js":
webmake_magic_jsonp_function( // the jsonp callback function
"a", // origin of code loading (used for identifing the stored function)
{
"c": function(/* ... */, process) {
// the content of the big libary
},
"d": function(/* ... */, process) {
// d.js is here a dependency of c.js (optional)
}
}
```

This feature may makes the compile process a big complexer.

It may be useful for:

* loading parts of your webapp when accessing them
* loading polyfills only when necessary
* increase startup time