Skip to content

Commit

Permalink
added contexts, docs and examples
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Mar 11, 2012
1 parent a3d4bb4 commit 14b42ac
Show file tree
Hide file tree
Showing 25 changed files with 668 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/node_modules
/test/js
/test/browsertest/js
/example/js
/examples/*/js
59 changes: 49 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ File 2: 1.web.js
- code of module d and dependencies
```

See [details](modules-webpack/tree/master/example) for exact output.
See [details](modules-webpack/tree/master/examples/code-splitting) for exact output.

## Browser replacements

Expand All @@ -87,19 +87,52 @@ Modules in `web_modules` replace modules in `node_modules`.

TODO specify replacements in options

## require.context

If the `require`d module is not known while compile time we get into a problem.
A solution is the method `require.context` which takes a directory as parameter
and returns a function which behaves like the `require` function issued from a file
in this directory (but only if used for files in that directory).

### Example

We have a directory full of templates, which are compiled javascript files.
A template should be loaded by template name.

``` javascript
var requireTemplate = require.context("./templates");
function getTemplate(templateName) {
return requireTemplate("./" + templateName);
}
```

In addition to that `webpack` uses the `require.context` function automatically
if you use variables or other non-literal things in the `require` function.
That means the following code behaves like the above:

``` javascript
function getTemplate(templateName) {
return require("./templates/" + templateName);
}
// is compiled like: return require.context("./templates")("./"+templateName)
```

See [details](modules-webpack/tree/master/examples/require.context) for complete example.


*Warning: The complete code in the directory are included. So use it carefully.*

## Limitations

### `require`-function

As dependencies are resolved before running:
* `require` should not be overwritten
* `require` should not be called indirect as `var r = require; r("./a");`
* arguments of `require` should be literals. `"./abc" + "/def"` is allowed to support long lines.
* `require.ensure` has the same limitations as `require`
* `require` should not be called indirect as `var r = require; r("./a");`. Use `require.context`?
* `require.ensure` should not be overwritten or called indirect
* the function passed to `require.ensure` should be inlined in the call.

TODO allow variables passing to `require` like `require("./templates/" + mytemplate)`
(this will cause all modules matching this pattern to be included in addition to a mapping table)
* `require.context` should not be overwritten or called indirect
* the argument to `require.context` should be a literal or addition of multiple literals

### node.js specific modules

Expand Down Expand Up @@ -173,7 +206,7 @@ add absolute filenames of input files as comments
#### `callback`
`function(err, source / stats)`
`source` if `options.output` is not set
else `stats` as json see [example](/modules-webpack/tree/master/example)
else `stats` as json see [example](/modules-webpack/tree/master/examples/code-splitting)

## medikoo/modules-webmake

Expand All @@ -183,14 +216,20 @@ So big credit goes to medikoo.
However `webpack` has big differences:

`webpack` replaces module names and paths with numbers. `webmake` don't do that and do resolves requires on client-side.
This design of `webmake` wes intended to support variables as arguments to require calls.
This design of `webmake` was intended to support variables as arguments to require calls.
`webpack` resolves requires in compile time and have no resolve code on client side. This results in smaller bundles.
Variables as argments will be handled different and with more limitations.

Another limitation in `webmake` which are based on the previous one is that modules must be in the current package scope.
In `webpack` this is not a restriction.

The design of `webmake` causes all modules with the same name to overlap. This can be problematic if different submodules rely on specific versions of the same module. The behaivior also differs from the behaivior of node.js, because node.js installs a module for each instance in submodules and `webmake` cause them the merge into a single module which is only installed once. In `webpack` this is not the case. Different versions do not overlap and modules are installed multiple times. But in `webpack` this can (currently) cause duplicate code if a module is used in multiple modules. I want to face this issue (TODO).
The design of `webmake` causes all modules with the same name to overlap.
This can be problematic if different submodules rely on specific versions of the same module.
The behaivior also differs from the behaivior of node.js, because node.js installs a module for each instance in submodules and `webmake` cause them the merge into a single module which is only installed once.
In `webpack` this is not the case.
Different versions do not overlap and modules are installed multiple times.
But in `webpack` this can (currently) cause duplicate code if a module is used in multiple modules.
I want to face this issue (TODO).

`webmake` do (currently) not support Code Splitting.

Expand Down
138 changes: 138 additions & 0 deletions examples/code-splitted-require.context/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# example.js

``` javascript
function getTemplate(templateName, callback) {
require.ensure([], function(require) {
callback(require("../require.context/templates/"+templateName));
});
}
getTemplate("a", function(a) {
console.log(a);
});
getTemplate("b", function(b) {
console.log(b);
});
```

# js/output.js

``` javascript
/******/(function(document, undefined) {
/******/ return function(modules) {
/******/ var installedModules = {}, installedChunks = {0:1};
/******/ function require(moduleId) {
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ var module = installedModules[moduleId] = {
/******/ exports: {}
/******/ };
/******/ modules[moduleId](module, module.exports, require);
/******/ return module.exports;
/******/ }
/******/ require.ensure = function(chunkId, callback) {
/******/ if(installedChunks[chunkId] === 1) return callback(require);
/******/ if(installedChunks[chunkId] !== undefined)
/******/ installedChunks[chunkId].push(callback);
/******/ else {
/******/ installedChunks[chunkId] = [callback];
/******/ var head = document.getElementsByTagName('head')[0];
/******/ var script = document.createElement('script');
/******/ script.type = 'text/javascript';
/******/ script.src = modules.c+chunkId+modules.a;
/******/ head.appendChild(script);
/******/ }
/******/ };
/******/ window[modules.b] = function(chunkId, moreModules) {
/******/ for(var moduleId in moreModules)
/******/ modules[moduleId] = moreModules[moduleId];
/******/ var callbacks = installedChunks[chunkId];
/******/ installedChunks[chunkId] = 1;
/******/ for(var i = 0; i < callbacks.length; i++)
/******/ callbacks[i](require);
/******/ };
/******/ return require(0);
/******/ }
/******/})(document)
/******/({a:".output.js",b:"webpackJsonp",c:"",
/******/0: function(module, exports, require) {

function getTemplate(templateName, callback) {
require.ensure(1, function(require) {
callback(require(1)("./"+templateName));
});
}
getTemplate("a", function(a) {
console.log(a);
});
getTemplate("b", function(b) {
console.log(b);
});

/******/},
/******/
/******/})
```

# js/1.output.js

``` javascript
/******/webpackJsonp(1, {
/******/1: function(module, exports, require) {

/***/module.exports = function(name) {
/***/ var map = {"./b.js":3,"./a.js":2,"./c.js":4};
/***/ return require(map[name]||map[name+".web.js"]||map[name+".js"]);
/***/};

/******/},
/******/
/******/2: function(module, exports, require) {

module.exports = function() {
return "This text was generated by template A";
}

/******/},
/******/
/******/3: function(module, exports, require) {

module.exports = function() {
return "This text was generated by template B";
}

/******/},
/******/
/******/4: function(module, exports, require) {

module.exports = function() {
return "This text was generated by template C";
}

/******/},
/******/
/******/})
```

# Info

## Uncompressed

``` javascript
{ chunkCount: 2,
modulesCount: 5,
modulesIncludingDuplicates: 5,
modulesPerChunk: 2.5,
modulesFirstChunk: 1,
fileSizes: { 'output.js': 1855, '1.output.js': 729 } }
```

## Minimized (uglify-js, no zip)

``` javascript
{ chunkCount: 2,
modulesCount: 5,
modulesIncludingDuplicates: 5,
modulesPerChunk: 2.5,
modulesFirstChunk: 1,
fileSizes: { 'output.js': 683, '1.output.js': 404 } }
```
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ argv.shift();
argv.shift();
var extraArgs = argv.join(" ");

cp.exec("node ../bin/webpack.js "+extraArgs+" example.js js/output.js", function (error, stdout, stderr) {
cp.exec("node ../../bin/webpack.js "+extraArgs+" example.js js/output.js", function (error, stdout, stderr) {
console.log('stdout:\n' + stdout);
console.log('stderr:\n ' + stderr);
if (error !== null) {
Expand Down
11 changes: 11 additions & 0 deletions examples/code-splitted-require.context/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function getTemplate(templateName, callback) {
require.ensure([], function(require) {
callback(require("../require.context/templates/"+templateName));
});
}
getTemplate("a", function(a) {
console.log(a);
});
getTemplate("b", function(b) {
console.log(b);
});
2 changes: 1 addition & 1 deletion example/README.md → examples/code-splitting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ webpackJsonp(1,{3:function(a,b,c){},4:function(a,b,c){}})
fileSizes: { 'output.js': 1948, '1.output.js': 200 } }
```

## Compress (uglify-js, no zip)
## Minimized (uglify-js, no zip)

``` javascript
{ chunkCount: 2,
Expand Down
14 changes: 14 additions & 0 deletions examples/code-splitting/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var cp = require('child_process');

var argv = process.argv;
argv.shift();
argv.shift();
var extraArgs = argv.join(" ");

cp.exec("node ../../bin/webpack.js "+extraArgs+" example.js js/output.js", function (error, stdout, stderr) {
console.log('stdout:\n' + stdout);
console.log('stderr:\n ' + stderr);
if (error !== null) {
console.log('error: ' + error);
}
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 14b42ac

Please sign in to comment.