mirror of https://github.com/webpack/webpack.git
better error handling, added conditional (?: operator) support, some docs
This commit is contained in:
parent
f5651c8fa8
commit
4c6fa00428
405
README.md
405
README.md
|
@ -1,7 +1,5 @@
|
||||||
# modules-webpack
|
# modules-webpack
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
As developer you want to reuse existing code.
|
As developer you want to reuse existing code.
|
||||||
As with node.js and web all file are already in the same language, but it is extra work to use your code with the node.js module system and the browser.
|
As with node.js and web all file are already in the same language, but it is extra work to use your code with the node.js module system and the browser.
|
||||||
The goal of `webpack` is to bundle CommonJs modules into javascript files which can be loaded by `<script>`-tags.
|
The goal of `webpack` is to bundle CommonJs modules into javascript files which can be loaded by `<script>`-tags.
|
||||||
|
@ -14,9 +12,18 @@ The result is a smaller inital code download which results in faster page load.
|
||||||
|
|
||||||
* bundle CommonJs modules for browser
|
* bundle CommonJs modules for browser
|
||||||
* reuse server-side code (node.js) on client-side
|
* reuse server-side code (node.js) on client-side
|
||||||
* create multiple files which are loaded on demand
|
* create multiple files which are loaded on demand (faster page load in big webapps)
|
||||||
* dependencies managed for you
|
* dependencies managed for you, on compile time
|
||||||
* faster page load in big webapps
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
* minimize code size
|
||||||
|
* minimize code size on inital download
|
||||||
|
* download code only on demand
|
||||||
|
* hide development details, like module names and folder structure
|
||||||
|
* require minimal configuration
|
||||||
|
* load polyfills for node-specific things if used
|
||||||
|
* offer replacements for node buildin libaries
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
@ -67,6 +74,7 @@ require.ensure(["c"], function(require) {
|
||||||
|
|
||||||
```
|
```
|
||||||
File 1: web.js
|
File 1: web.js
|
||||||
|
- code of that file
|
||||||
- code of module a and dependencies
|
- code of module a and dependencies
|
||||||
- code of module b and dependencies
|
- code of module b and dependencies
|
||||||
|
|
||||||
|
@ -77,6 +85,20 @@ File 2: 1.web.js
|
||||||
|
|
||||||
See [details](modules-webpack/tree/master/examples/code-splitting) for exact output.
|
See [details](modules-webpack/tree/master/examples/code-splitting) for exact output.
|
||||||
|
|
||||||
|
## Reusing node.js code
|
||||||
|
|
||||||
|
`webpack` was built to support most of the code that was coded for node.js environment.
|
||||||
|
For example this works out of the box:
|
||||||
|
|
||||||
|
* `require("./templates/" + templateName);`
|
||||||
|
* `require(condition ? "moduleA" : condition2 ? "moduleB" : "./localStuff");`
|
||||||
|
* `function xyz(require) { require("text"); } xyz(function(a) { console.log(a) });`
|
||||||
|
* `var r = require; r("./file");` with warning
|
||||||
|
* `function xyz(require) { require("./file"); } xyz(require);` with warning
|
||||||
|
* `try { require("missingModule"); } catch(e) { console.log("missing") }` with warning
|
||||||
|
* `var require = function(a) { console.log(a) }; require("text");`
|
||||||
|
* `if(condition) require("optionalModule")` with warning if missing
|
||||||
|
|
||||||
## Browser replacements
|
## Browser replacements
|
||||||
|
|
||||||
Somethings it happens that browsers require other code than node.js do.
|
Somethings it happens that browsers require other code than node.js do.
|
||||||
|
@ -131,7 +153,6 @@ There is a warning emitted in this case.
|
||||||
|
|
||||||
As dependencies are resolved before running:
|
As dependencies are resolved before running:
|
||||||
|
|
||||||
* `require` should not be overwritten by variable declaration (`var require = ...`), by function parameter is allowed `function(require) {...}`.
|
|
||||||
* `require.ensure` should not be overwritten or called indirect
|
* `require.ensure` should not be overwritten or called indirect
|
||||||
* `require.context` should not be overwritten or called indirect
|
* `require.context` should not be overwritten or called indirect
|
||||||
* the argument to `require.context` should be a literal or addition of multiple literals
|
* the argument to `require.context` should be a literal or addition of multiple literals
|
||||||
|
@ -141,7 +162,7 @@ The following cases could result in too much code in result file if used wrong:
|
||||||
|
|
||||||
* indirect call of `require`: `var r = require; r("./file");`
|
* indirect call of `require`: `var r = require; r("./file");`
|
||||||
* `require.context`. It includes the whole directory.
|
* `require.context`. It includes the whole directory.
|
||||||
* expressions in require arguments: `require(variable)`, `require(condition ? "a" : "b")` (TODO)
|
* expressions in require arguments: `require(variable)`, webpack is smart enough for this `require(condition ? "a" : "b")`
|
||||||
* the function passed to `require.ensure` is not inlined in the call.
|
* the function passed to `require.ensure` is not inlined in the call.
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,6 +170,8 @@ The following cases could result in too much code in result file if used wrong:
|
||||||
|
|
||||||
As node.js specific modules like `fs` will not work in browser they are not included and cause an error.
|
As node.js specific modules like `fs` will not work in browser they are not included and cause an error.
|
||||||
You should replace them by own modules if you want to use them.
|
You should replace them by own modules if you want to use them.
|
||||||
|
For some modules are replacements included in `webpack`.
|
||||||
|
Some credit goes to the browserify contributors, as I took some replacements from them.
|
||||||
|
|
||||||
```
|
```
|
||||||
web_modules
|
web_modules
|
||||||
|
@ -157,7 +180,7 @@ web_modules
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
TODO provide some replacements
|
TODO provide some replacements (half way done...)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -225,33 +248,359 @@ add absolute filenames of input files as comments
|
||||||
`source` if `options.output` is not set
|
`source` if `options.output` is not set
|
||||||
else `stats` as json see [example](/modules-webpack/tree/master/examples/code-splitting)
|
else `stats` as json see [example](/modules-webpack/tree/master/examples/code-splitting)
|
||||||
|
|
||||||
## medikoo/modules-webmake
|
## Comparison
|
||||||
|
|
||||||
`webpack` as originally intended as fork for `webmake` for @medikoo so it shared several ideas with it.
|
<table>
|
||||||
So big credit goes to medikoo.
|
<tr>
|
||||||
|
<th>
|
||||||
|
Feature
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
sokra/<br/>modules-<br/>webpack
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
medikoo/<br/>modules-<br/>webmake
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
substack/<br/>node-<br/>browserify
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
However `webpack` has big differences:
|
<tr>
|
||||||
|
<td>
|
||||||
|
single bundle
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
`webpack` replaces module names and paths with numbers. `webmake` don't do that and do resolves requires on client-side.
|
<tr>
|
||||||
This design of `webmake` was intended to support variables as arguments to require calls.
|
<td>
|
||||||
`webpack` resolves requires in compile time and have no resolve code on client side. This results in smaller bundles.
|
multiple bundles, Code Splitting
|
||||||
Variables as arguments will be handled different and with more limitations in `webpack`.
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
Another limitation in `webmake` which are based on the previous one is that modules must be in the current package scope.
|
<tr>
|
||||||
In `webpack` this is not a restriction.
|
<td>
|
||||||
|
indirect require
|
||||||
|
<code>var r = require; r("./file");</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
in directory
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
include by config option
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
There is no `require.context` in `webmake`. Therefore there is a forced include list in options which allows modules to be required even if the names were not available at compile time.
|
<tr>
|
||||||
|
<td>
|
||||||
|
concat in require
|
||||||
|
<code>require("./fi" + "le")</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
The design of `webmake` causes all modules with the same name to overlap.
|
<tr>
|
||||||
This can be problematic if different submodules rely on specific versions of the same module.
|
<td>
|
||||||
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.
|
variables in require (local)
|
||||||
In `webpack` this is not the case.
|
<code>require("./templates/"+template)</code>
|
||||||
Different versions do not overlap and modules are installed multiple times.
|
</td>
|
||||||
But in `webpack` this can (currently) cause duplicate code if a module is used in multiple modules.
|
<td>
|
||||||
I want to face this issue (TODO).
|
yes, complete directory included
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
include by config option
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
`webmake` do (currently) not support Code Splitting.
|
<tr>
|
||||||
But medikoo said he works at some related feature.
|
<td>
|
||||||
|
variables in require (global)
|
||||||
|
<code>require(moduleName)</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
include by config option
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
node buildin libs
|
||||||
|
<code>require("http");</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
some
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
many
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>process</code> polyfill
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes, on demand
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes, ever
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>module</code> polyfill
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes, on demand
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>require.resolve</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>global</code> to <code>window</code> mapping
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
requirable files
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
filesystem
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
directory scope
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
filesystem
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
different modules with same name
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
eliminate duplicate code
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
require JSON
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
plugins
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
compile coffee script
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
watch mode
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
debug mode
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
libaries
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
on global obj
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
requirable
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
browser replacements
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<code>web_modules</code> and <code>.web.js</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
by alias config option
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
compiles with (optional) modules missing
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
yes, emit warnings
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,8 @@ function addModule(depTree, context, module, options, reason, callback) {
|
||||||
};
|
};
|
||||||
addModule(depTree, path.dirname(filename), moduleName, options, reason, function(err, moduleId) {
|
addModule(depTree, path.dirname(filename), moduleName, options, reason, function(err, moduleId) {
|
||||||
if(err) {
|
if(err) {
|
||||||
errors.push(err+"\n @ " + filename + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")");
|
depTree.warnings.push("Cannot find module '" + moduleName + "'\n " + err +
|
||||||
|
"\n @ " + filename + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")");
|
||||||
} else {
|
} else {
|
||||||
requires[moduleName].forEach(function(requireItem) {
|
requires[moduleName].forEach(function(requireItem) {
|
||||||
requireItem.id = moduleId;
|
requireItem.id = moduleId;
|
||||||
|
@ -254,7 +255,8 @@ function addContextModule(depTree, context, contextModuleName, options, reason,
|
||||||
};
|
};
|
||||||
addModule(depTree, null, filename, options, reason, function(err, moduleId) {
|
addModule(depTree, null, filename, options, reason, function(err, moduleId) {
|
||||||
if(err) {
|
if(err) {
|
||||||
endOne(err);
|
depTree.warnings.push("A file in context was excluded because of error: " + err);
|
||||||
|
endOne();
|
||||||
} else {
|
} else {
|
||||||
contextModule.requires.push({id: moduleId});
|
contextModule.requires.push({id: moduleId});
|
||||||
contextModule.requireMap[moduleName + "/" + file] = moduleId;
|
contextModule.requireMap[moduleName + "/" + file] = moduleId;
|
||||||
|
@ -274,17 +276,6 @@ function addContextModule(depTree, context, contextModuleName, options, reason,
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var extensionsAccess = [];
|
|
||||||
extensions.forEach(function(ext) {
|
|
||||||
extensionsAccess.push("||map[name+\"");
|
|
||||||
extensionsAccess.push(ext.replace(/\\/g, "\\\\").replace(/"/g, "\\\""));
|
|
||||||
extensionsAccess.push("\"]");
|
|
||||||
});
|
|
||||||
|
|
||||||
contextModule.source = "/***/module.exports = function(name) {\n" +
|
|
||||||
"/***/\tvar map = " + JSON.stringify(contextModule.requireMap) + ";\n" +
|
|
||||||
"/***/\treturn require(map[name]" + extensionsAccess.join("") + ");\n" +
|
|
||||||
"/***/};";
|
|
||||||
callback(null, contextModule.id);
|
callback(null, contextModule.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -313,7 +304,8 @@ function addModuleToChunk(depTree, context, chunkId, options) {
|
||||||
depTree.chunks[chunkId].modules[context.id] = "include";
|
depTree.chunks[chunkId].modules[context.id] = "include";
|
||||||
if(context.requires) {
|
if(context.requires) {
|
||||||
context.requires.forEach(function(requireItem) {
|
context.requires.forEach(function(requireItem) {
|
||||||
addModuleToChunk(depTree, depTree.modulesById[requireItem.id], chunkId, options);
|
if(requireItem.id)
|
||||||
|
addModuleToChunk(depTree, depTree.modulesById[requireItem.id], chunkId, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(context.asyncs) {
|
if(context.asyncs) {
|
||||||
|
|
51
lib/parse.js
51
lib/parse.js
|
@ -177,13 +177,24 @@ function walkExpression(context, expression) {
|
||||||
break;
|
break;
|
||||||
case "CallExpression":
|
case "CallExpression":
|
||||||
var noCallee = false;
|
var noCallee = false;
|
||||||
if(context.overwrite.indexOf("require") === -1 &&
|
if(context.overwrite.indexOf("require") === -1 &&
|
||||||
expression.callee && expression.arguments &&
|
expression.callee && expression.arguments &&
|
||||||
expression.arguments.length == 1 &&
|
expression.arguments.length == 1 &&
|
||||||
expression.callee.type === "Identifier" &&
|
expression.callee.type === "Identifier" &&
|
||||||
expression.callee.name === "require") {
|
expression.callee.name === "require") {
|
||||||
var param = parseCalculatedString(expression.arguments[0]);
|
var param = parseCalculatedString(expression.arguments[0]);
|
||||||
if(param.code) {
|
if(param.conditional) {
|
||||||
|
context.requires = context.requires || [];
|
||||||
|
param.conditional.forEach(function(paramItem) {
|
||||||
|
context.requires.push({
|
||||||
|
name: paramItem.value,
|
||||||
|
valueRange: paramItem.range,
|
||||||
|
line: expression.loc.start.line,
|
||||||
|
column: expression.loc.start.column
|
||||||
|
});
|
||||||
|
console.dir(context.requires[context.requires.length-1]);
|
||||||
|
});
|
||||||
|
} else if(param.code) {
|
||||||
// make context
|
// make context
|
||||||
var pos = param.value.indexOf("/");
|
var pos = param.value.indexOf("/");
|
||||||
context.contexts = context.contexts || [];
|
context.contexts = context.contexts || [];
|
||||||
|
@ -222,7 +233,7 @@ function walkExpression(context, expression) {
|
||||||
}
|
}
|
||||||
noCallee = true;
|
noCallee = true;
|
||||||
}
|
}
|
||||||
if(context.overwrite.indexOf("require") === -1 &&
|
if(context.overwrite.indexOf("require") === -1 &&
|
||||||
expression.callee && expression.arguments &&
|
expression.callee && expression.arguments &&
|
||||||
expression.arguments.length >= 1 &&
|
expression.arguments.length >= 1 &&
|
||||||
expression.callee.type === "MemberExpression" &&
|
expression.callee.type === "MemberExpression" &&
|
||||||
|
@ -248,7 +259,7 @@ function walkExpression(context, expression) {
|
||||||
context = newContext;
|
context = newContext;
|
||||||
noCallee = true;
|
noCallee = true;
|
||||||
}
|
}
|
||||||
if(context.overwrite.indexOf("require") === -1 &&
|
if(context.overwrite.indexOf("require") === -1 &&
|
||||||
expression.callee && expression.arguments &&
|
expression.callee && expression.arguments &&
|
||||||
expression.arguments.length == 1 &&
|
expression.arguments.length == 1 &&
|
||||||
expression.callee.type === "MemberExpression" &&
|
expression.callee.type === "MemberExpression" &&
|
||||||
|
@ -284,7 +295,7 @@ function walkExpression(context, expression) {
|
||||||
walkExpression(context, expression.property);
|
walkExpression(context, expression.property);
|
||||||
break;
|
break;
|
||||||
case "Identifier":
|
case "Identifier":
|
||||||
if(context.overwrite.indexOf("require") === -1 &&
|
if(context.overwrite.indexOf("require") === -1 &&
|
||||||
expression.name === "require") {
|
expression.name === "require") {
|
||||||
context.contexts = context.contexts || [];
|
context.contexts = context.contexts || [];
|
||||||
var newContext = {
|
var newContext = {
|
||||||
|
@ -296,7 +307,7 @@ function walkExpression(context, expression) {
|
||||||
column: expression.loc.start.column
|
column: expression.loc.start.column
|
||||||
};
|
};
|
||||||
context.contexts.push(newContext);
|
context.contexts.push(newContext);
|
||||||
} else if(context.overwrite.indexOf(expression.name) === -1 &&
|
} else if(context.overwrite.indexOf(expression.name) === -1 &&
|
||||||
expression.name in context.options.overwrites) {
|
expression.name in context.options.overwrites) {
|
||||||
context.requires = context.requires || [];
|
context.requires = context.requires || [];
|
||||||
context.requires.push({
|
context.requires.push({
|
||||||
|
@ -310,17 +321,6 @@ function walkExpression(context, expression) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function functionParamsContainsRequire(params) {
|
|
||||||
if(!params) return false;
|
|
||||||
var found = false;
|
|
||||||
params.forEach(function(param) {
|
|
||||||
if(param.type === "Identifier" &&
|
|
||||||
param.name === "require")
|
|
||||||
found = true;
|
|
||||||
});
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addOverwrites(context, params) {
|
function addOverwrites(context, params) {
|
||||||
var l = context.overwrite.length;
|
var l = context.overwrite.length;
|
||||||
if(!params) return l;
|
if(!params) return l;
|
||||||
|
@ -329,7 +329,7 @@ function addOverwrites(context, params) {
|
||||||
context.ignoreOverride = false;
|
context.ignoreOverride = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(param.type === "Identifier" &&
|
if(param.type === "Identifier" &&
|
||||||
param.name in context.options.overwrites)
|
param.name in context.options.overwrites)
|
||||||
context.overwrite.push(param.name);
|
context.overwrite.push(param.name);
|
||||||
});
|
});
|
||||||
|
@ -363,6 +363,21 @@ function parseCalculatedString(expression) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "ConditionalExpression":
|
||||||
|
var consequent = parseCalculatedString(expression.consequent);
|
||||||
|
var alternate = parseCalculatedString(expression.alternate);
|
||||||
|
var items = [];
|
||||||
|
if(consequent.conditional)
|
||||||
|
Array.prototype.push.apply(items, consequent.conditional);
|
||||||
|
else if(!consequent.code)
|
||||||
|
items.push(consequent);
|
||||||
|
else break;
|
||||||
|
if(alternate.conditional)
|
||||||
|
Array.prototype.push.apply(items, alternate.conditional);
|
||||||
|
else if(!alternate.code)
|
||||||
|
items.push(alternate);
|
||||||
|
else break;
|
||||||
|
return {value: "", code: true, conditional: items};
|
||||||
case "Literal":
|
case "Literal":
|
||||||
return {range: expression.range, value: expression.value+""};
|
return {range: expression.range, value: expression.value+""};
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = function resolve(context, identifier, options, callback) {
|
||||||
function finalResult(err, absoluteFilename) {
|
function finalResult(err, absoluteFilename) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback("Module \"" + identifier + "\" not found in context \"" +
|
callback("Module \"" + identifier + "\" not found in context \"" +
|
||||||
context + "\"\n" + err);
|
context + "\"\n " + err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback(null, absoluteFilename);
|
callback(null, absoluteFilename);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/******/ return function(modules) {
|
/******/ return function(modules) {
|
||||||
/******/ var installedModules = {}, installedChunks = {0:1};
|
/******/ var installedModules = {}, installedChunks = {0:1};
|
||||||
/******/ function require(moduleId) {
|
/******/ function require(moduleId) {
|
||||||
|
/******/ if(typeof moduleId !== "number") throw new Error("Cannot find module '"+moduleId+"'");
|
||||||
/******/ if(installedModules[moduleId])
|
/******/ if(installedModules[moduleId])
|
||||||
/******/ return installedModules[moduleId].exports;
|
/******/ return installedModules[moduleId].exports;
|
||||||
/******/ var module = installedModules[moduleId] = {
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/******/(function(modules) {
|
/******/(function(modules) {
|
||||||
/******/ var installedModules = {};
|
/******/ var installedModules = {};
|
||||||
/******/ function require(moduleId) {
|
/******/ function require(moduleId) {
|
||||||
|
/******/ if(typeof moduleId !== "number") throw new Error("Cannot find module '"+moduleId+"'");
|
||||||
/******/ if(installedModules[moduleId])
|
/******/ if(installedModules[moduleId])
|
||||||
/******/ return installedModules[moduleId].exports;
|
/******/ return installedModules[moduleId].exports;
|
||||||
/******/ var module = installedModules[moduleId] = {
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
|
|
@ -25,7 +25,7 @@ module.exports = function(depTree, chunk, options) {
|
||||||
buffer.push(module.filename);
|
buffer.push(module.filename);
|
||||||
buffer.push(" ***/\n\n");
|
buffer.push(" ***/\n\n");
|
||||||
}
|
}
|
||||||
buffer.push(writeSource(module));
|
buffer.push(writeSource(module, options));
|
||||||
buffer.push("\n\n/******/},\n/******/\n");
|
buffer.push("\n\n/******/},\n/******/\n");
|
||||||
}
|
}
|
||||||
return buffer.join("");
|
return buffer.join("");
|
||||||
|
|
|
@ -6,18 +6,44 @@ function stringify(str) {
|
||||||
return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"';
|
return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(module) {
|
module.exports = function(module, options) {
|
||||||
|
if(!module.source) {
|
||||||
|
if(module.requireMap) {
|
||||||
|
var extensions = (options.resolve && options.resolve.extensions) || [".web.js", ".js"];
|
||||||
|
var extensionsAccess = [];
|
||||||
|
extensions.forEach(function(ext) {
|
||||||
|
extensionsAccess.push("||map[name+\"");
|
||||||
|
extensionsAccess.push(ext.replace(/\\/g, "\\\\").replace(/"/g, "\\\""));
|
||||||
|
extensionsAccess.push("\"]");
|
||||||
|
});
|
||||||
|
|
||||||
|
return "/***/function err(name) { throw new Error(\"Cannot find module '\"+name+\"'\") }\n"+
|
||||||
|
"/***/module.exports = function(name) {\n" +
|
||||||
|
"/***/\tvar map = " + JSON.stringify(module.requireMap) + ";\n" +
|
||||||
|
"/***/\treturn require(map[name]" + extensionsAccess.join("") + "||(err(name)));\n" +
|
||||||
|
"/***/};";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
var replaces = []; // { from: 123, to: 125, value: "4" }
|
var replaces = []; // { from: 123, to: 125, value: "4" }
|
||||||
function genReplaceRequire(requireItem) {
|
function genReplaceRequire(requireItem) {
|
||||||
if(requireItem.expressionRange && requireItem.id !== undefined) {
|
if(requireItem.id !== undefined) {
|
||||||
var prefix = "";
|
var prefix = "";
|
||||||
if(requireItem.name)
|
if(requireItem.name)
|
||||||
prefix += "/* " + requireItem.name + " */";
|
prefix += "/* " + requireItem.name + " */";
|
||||||
replaces.push({
|
if(requireItem.expressionRange) {
|
||||||
from: requireItem.expressionRange[0],
|
replaces.push({
|
||||||
to: requireItem.expressionRange[1],
|
from: requireItem.expressionRange[0],
|
||||||
value: "require(" + prefix + requireItem.id + ")"
|
to: requireItem.expressionRange[1],
|
||||||
});
|
value: "require(" + prefix + requireItem.id + ")"
|
||||||
|
});
|
||||||
|
} else if(requireItem.valueRange) {
|
||||||
|
replaces.push({
|
||||||
|
from: requireItem.valueRange[0],
|
||||||
|
to: requireItem.valueRange[1],
|
||||||
|
value: prefix + requireItem.id
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function genContextReplaces(contextItem) {
|
function genContextReplaces(contextItem) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "webpack",
|
"name": "webpack",
|
||||||
"version": "0.2.5",
|
"version": "0.2.6",
|
||||||
"author": "Tobias Koppers @sokra",
|
"author": "Tobias Koppers @sokra",
|
||||||
"description": "Packs CommonJs Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand.",
|
"description": "Packs CommonJs Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// Polyfill for node.js
|
// Polyfill for node.js
|
||||||
// adds require.ensure
|
// adds require.ensure
|
||||||
// call it like this: require("webpack/require-polyfill")(require);
|
// call it like this: require("webpack/require-polyfill")(require);
|
||||||
// This is only required when you want to use require.ensure in server-side code
|
// This is only required when you want to use require.ensure or require.context
|
||||||
// which should be so only in rar cases.
|
// in server-side code which should be so only in rar cases.
|
||||||
module.exports = function(req) {
|
module.exports = function(req) {
|
||||||
if(!req.ensure) {
|
if(!req.ensure) {
|
||||||
req.ensure = function(array, callback) {
|
req.ensure = function(array, callback) {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
))) This results in a syntax error loading this file.
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = "file1";
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = "file2";
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = "file3";
|
|
@ -27,7 +27,28 @@ function testFunc(abc, require) {
|
||||||
return require;
|
return require;
|
||||||
}
|
}
|
||||||
window.test(testFunc(333, 678) === 678, "require overwrite in named function");
|
window.test(testFunc(333, 678) === 678, "require overwrite in named function");
|
||||||
|
function testCase(number) {
|
||||||
|
//window.test(require("./folder/file" + (number === 1 ? 1 : "2")) === "file" + number);
|
||||||
|
window.test(require(number === 1 ? "../folder/file1" : number === 2 ? "../folder/file2" : number === 3 ? "../folder/file3" : "./missingModule") === "file" + number, "?: operator in require do not create context, test "+number);
|
||||||
|
}
|
||||||
|
testCase(1);
|
||||||
|
testCase(2);
|
||||||
|
testCase(3);
|
||||||
|
|
||||||
|
var error = null;
|
||||||
|
try {
|
||||||
|
testCase(4);
|
||||||
|
} catch(e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
window.test(error instanceof Error, "Missing module should throw Error, indirect");
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
require("./missingModule2");
|
||||||
|
} catch(e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
window.test(error instanceof Error, "Missing module should throw Error, direct");
|
||||||
|
|
||||||
require.ensure([], function(require) {
|
require.ensure([], function(require) {
|
||||||
var contextRequire = require.context(".");
|
var contextRequire = require.context(".");
|
||||||
|
|
Loading…
Reference in New Issue