Skip to content

Commit 5ba77f9

Browse files
authored
Merge branch 'master' into feature/import-chunk-name
2 parents 1fdf800 + accc94c commit 5ba77f9

46 files changed

Lines changed: 948 additions & 353 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 131 additions & 131 deletions
Large diffs are not rendered by default.

benchmark/createFixtures2.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ try {
99

1010
function genModule(prefix, depth, asyncDepth, multiplex, r, circular) {
1111
var source = [];
12-
var async = depth >= asyncDepth;
13-
if(!async)
12+
var isAsync = depth >= asyncDepth;
13+
if(!isAsync)
1414
circular.push(path.resolve(fixtures, prefix + "/index.js"));
1515
source.push("(function() {");
1616
var m = (r % multiplex) + 1;
@@ -23,7 +23,7 @@ function genModule(prefix, depth, asyncDepth, multiplex, r, circular) {
2323
sum += genModule(prefix + "/" + i, depth - 1, asyncDepth, multiplex, (r + i + depth) * m + i + depth, circular);
2424
source.push("require(" + JSON.stringify("./" + i) + ");");
2525
if(i === 0) {
26-
if(async)
26+
if(isAsync)
2727
source.push("}); require.ensure([], function() {");
2828
}
2929
}
@@ -42,8 +42,8 @@ for(var i = 2; i < 14; i++) {
4242
console.log("generated tree", i, count);
4343
}
4444

45-
for(var i = 2; i < 14; i++) {
46-
var count = genModule("async-tree-" + i, 6, 1, i, 0, []);
45+
for(i = 2; i < 14; i++) {
46+
count = genModule("async-tree-" + i, 6, 1, i, 0, []);
4747
console.log("generated async tree", i, count);
4848
}
4949

lib/HotModuleReplacement.runtime.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,31 @@ module.exports = function() {
4545
};
4646
};
4747
for(var name in $require$) {
48-
if(Object.prototype.hasOwnProperty.call($require$, name)) {
48+
if(Object.prototype.hasOwnProperty.call($require$, name) && name !== "e") {
4949
Object.defineProperty(fn, name, ObjectFactory(name));
5050
}
5151
}
52-
Object.defineProperty(fn, "e", {
53-
enumerable: true,
54-
value: function(chunkId) {
55-
if(hotStatus === "ready")
56-
hotSetStatus("prepare");
57-
hotChunksLoading++;
58-
return $require$.e(chunkId).then(finishChunkLoading, function(err) {
59-
finishChunkLoading();
60-
throw err;
61-
});
52+
fn.e = function(chunkId) {
53+
if(hotStatus === "ready")
54+
hotSetStatus("prepare");
55+
hotChunksLoading++;
56+
return $require$.e(chunkId).then(finishChunkLoading, function(err) {
57+
finishChunkLoading();
58+
throw err;
59+
});
6260

63-
function finishChunkLoading() {
64-
hotChunksLoading--;
65-
if(hotStatus === "prepare") {
66-
if(!hotWaitingFilesMap[chunkId]) {
67-
hotEnsureUpdateChunk(chunkId);
68-
}
69-
if(hotChunksLoading === 0 && hotWaitingFiles === 0) {
70-
hotUpdateDownloaded();
71-
}
61+
function finishChunkLoading() {
62+
hotChunksLoading--;
63+
if(hotStatus === "prepare") {
64+
if(!hotWaitingFilesMap[chunkId]) {
65+
hotEnsureUpdateChunk(chunkId);
66+
}
67+
if(hotChunksLoading === 0 && hotWaitingFiles === 0) {
68+
hotUpdateDownloaded();
7269
}
7370
}
7471
}
75-
});
72+
};
7673
return fn;
7774
}
7875

lib/IgnorePlugin.js

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,60 @@ class IgnorePlugin {
88
constructor(resourceRegExp, contextRegExp) {
99
this.resourceRegExp = resourceRegExp;
1010
this.contextRegExp = contextRegExp;
11+
12+
this.checkIgnore = this.checkIgnore.bind(this);
13+
}
14+
15+
/*
16+
* Only returns true if a "resourceRegExp" exists
17+
* and the resource given matches the regexp.
18+
*/
19+
checkResouce(resource) {
20+
if(!this.resourceRegExp) {
21+
return false;
22+
}
23+
return this.resourceRegExp.test(resource);
24+
}
25+
26+
/*
27+
* Returns true if contextRegExp does not exist
28+
* or if context matches the given regexp.
29+
*/
30+
checkContext(context) {
31+
if(!this.contextRegExp) {
32+
return true;
33+
}
34+
return this.contextRegExp.test(context);
35+
}
36+
37+
/*
38+
* Returns true if result should be ignored.
39+
* false if it shouldn't.
40+
*
41+
* Not that if "contextRegExp" is given, both the "resourceRegExp"
42+
* and "contextRegExp" have to match.
43+
*/
44+
checkResult(result) {
45+
if(!result) {
46+
return true;
47+
}
48+
return this.checkResouce(result.request) && this.checkContext(result.context);
49+
}
50+
51+
checkIgnore(result, callback) {
52+
// check if result is ignored
53+
if(this.checkResult(result)) {
54+
return callback();
55+
}
56+
return callback(null, result);
1157
}
1258

1359
apply(compiler) {
14-
const resourceRegExp = this.resourceRegExp;
15-
const contextRegExp = this.contextRegExp;
1660
compiler.plugin("normal-module-factory", (nmf) => {
17-
nmf.plugin("before-resolve", (result, callback) => {
18-
if(!result) return callback();
19-
if(resourceRegExp.test(result.request) &&
20-
(!contextRegExp || contextRegExp.test(result.context))) {
21-
return callback();
22-
}
23-
return callback(null, result);
24-
});
61+
nmf.plugin("before-resolve", this.checkIgnore);
2562
});
2663
compiler.plugin("context-module-factory", (cmf) => {
27-
cmf.plugin("before-resolve", (result, callback) => {
28-
if(!result) return callback();
29-
if(resourceRegExp.test(result.request)) {
30-
return callback();
31-
}
32-
return callback(null, result);
33-
});
64+
cmf.plugin("before-resolve", this.checkIgnore);
3465
});
3566
}
3667
}

lib/dependencies/RequireEnsureDependenciesBlock.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
77
const RequireEnsureDependency = require("./RequireEnsureDependency");
88

99
module.exports = class RequireEnsureDependenciesBlock extends AsyncDependenciesBlock {
10-
constructor(expr, fnExpression, chunkName, chunkNameRange, module, loc) {
10+
constructor(expr, successExpression, errorExpression, chunkName, chunkNameRange, module, loc) {
1111
super(chunkName, module, loc);
1212
this.expr = expr;
13-
const bodyRange = fnExpression && fnExpression.body && fnExpression.body.range;
14-
this.range = bodyRange && [bodyRange[0] + 1, bodyRange[1] - 1] || null;
13+
const successBodyRange = successExpression && successExpression.body && successExpression.body.range;
14+
const errorBodyRange = errorExpression && errorExpression.body && errorExpression.body.range;
15+
this.range = null;
16+
if(successBodyRange) {
17+
if(errorBodyRange) {
18+
this.range = [successBodyRange[0] + 1, errorBodyRange[1] - 1];
19+
} else {
20+
this.range = [successBodyRange[0] + 1, successBodyRange[1] - 1];
21+
}
22+
}
1523
this.chunkNameRange = chunkNameRange;
1624
const dep = new RequireEnsureDependency(this);
1725
dep.loc = loc;

lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,48 @@ module.exports = class RequireEnsureDependenciesBlockParserPlugin {
1313
parser.plugin("call require.ensure", expr => {
1414
let chunkName = null;
1515
let chunkNameRange = null;
16+
let errorExpressionArg = null;
17+
let errorExpression = null;
1618
switch(expr.arguments.length) {
17-
case 3:
19+
case 4:
1820
{
19-
const chunkNameExpr = parser.evaluateExpression(expr.arguments[2]);
21+
const chunkNameExpr = parser.evaluateExpression(expr.arguments[3]);
2022
if(!chunkNameExpr.isString()) return;
2123
chunkNameRange = chunkNameExpr.range;
2224
chunkName = chunkNameExpr.string;
2325
}
2426
// falls through
27+
case 3:
28+
{
29+
errorExpressionArg = expr.arguments[2];
30+
errorExpression = getFunctionExpression(errorExpressionArg);
31+
32+
if(!errorExpression && !chunkName) {
33+
const chunkNameExpr = parser.evaluateExpression(expr.arguments[2]);
34+
if(!chunkNameExpr.isString()) return;
35+
chunkNameRange = chunkNameExpr.range;
36+
chunkName = chunkNameExpr.string;
37+
}
38+
}
39+
// falls through
2540
case 2:
2641
{
2742
const dependenciesExpr = parser.evaluateExpression(expr.arguments[0]);
2843
const dependenciesItems = dependenciesExpr.isArray() ? dependenciesExpr.items : [dependenciesExpr];
29-
const fnExpressionArg = expr.arguments[1];
30-
const fnExpression = getFunctionExpression(fnExpressionArg);
44+
const successExpressionArg = expr.arguments[1];
45+
const successExpression = getFunctionExpression(successExpressionArg);
3146

32-
if(fnExpression) {
33-
parser.walkExpressions(fnExpression.expressions);
47+
if(successExpression) {
48+
parser.walkExpressions(successExpression.expressions);
49+
}
50+
if(errorExpression) {
51+
parser.walkExpressions(errorExpression.expressions);
3452
}
3553

36-
const dep = new RequireEnsureDependenciesBlock(expr, fnExpression ? fnExpression.fn : fnExpressionArg, chunkName, chunkNameRange, parser.state.module, expr.loc);
54+
const dep = new RequireEnsureDependenciesBlock(expr,
55+
successExpression ? successExpression.fn : successExpressionArg,
56+
errorExpression ? errorExpression.fn : errorExpressionArg,
57+
chunkName, chunkNameRange, parser.state.module, expr.loc);
3758
const old = parser.state.current;
3859
parser.state.current = dep;
3960
try {
@@ -52,18 +73,26 @@ module.exports = class RequireEnsureDependenciesBlockParserPlugin {
5273
if(failed) {
5374
return;
5475
}
55-
if(fnExpression) {
56-
if(fnExpression.fn.body.type === "BlockStatement")
57-
parser.walkStatement(fnExpression.fn.body);
76+
if(successExpression) {
77+
if(successExpression.fn.body.type === "BlockStatement")
78+
parser.walkStatement(successExpression.fn.body);
5879
else
59-
parser.walkExpression(fnExpression.fn.body);
80+
parser.walkExpression(successExpression.fn.body);
6081
}
6182
old.addBlock(dep);
6283
} finally {
6384
parser.state.current = old;
6485
}
65-
if(!fnExpression) {
66-
parser.walkExpression(fnExpressionArg);
86+
if(!successExpression) {
87+
parser.walkExpression(successExpressionArg);
88+
}
89+
if(errorExpression) {
90+
if(errorExpression.fn.body.type === "BlockStatement")
91+
parser.walkStatement(errorExpression.fn.body);
92+
else
93+
parser.walkExpression(errorExpression.fn.body);
94+
} else if(errorExpressionArg) {
95+
parser.walkExpression(errorExpressionArg);
6796
}
6897
return true;
6998
}

lib/dependencies/RequireEnsureDependency.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,17 @@ RequireEnsureDependency.Template = class RequireEnsureDependencyTemplate {
2121
apply(dep, source, outputOptions, requestShortener) {
2222
const depBlock = dep.block;
2323
const wrapper = DepBlockHelpers.getLoadDepBlockWrapper(depBlock, outputOptions, requestShortener, "require.ensure");
24+
const errorCallbackExists = depBlock.expr.arguments.length === 4 || (!depBlock.chunkName && depBlock.expr.arguments.length === 3);
2425
const startBlock = wrapper[0] + "(";
25-
const endBlock = `).bind(null, __webpack_require__)${wrapper[1]}__webpack_require__.oe${wrapper[2]}`;
26+
const middleBlock = `).bind(null, __webpack_require__)${wrapper[1]}`;
27+
const endBlock = `${middleBlock}__webpack_require__.oe${wrapper[2]}`;
2628
source.replace(depBlock.expr.range[0], depBlock.expr.arguments[1].range[0] - 1, startBlock);
27-
source.replace(depBlock.expr.arguments[1].range[1], depBlock.expr.range[1] - 1, endBlock);
29+
if(errorCallbackExists) {
30+
source.replace(depBlock.expr.arguments[1].range[1], depBlock.expr.arguments[2].range[0] - 1, middleBlock);
31+
source.replace(depBlock.expr.arguments[2].range[1], depBlock.expr.range[1] - 1, wrapper[2]);
32+
} else {
33+
source.replace(depBlock.expr.arguments[1].range[1], depBlock.expr.range[1] - 1, endBlock);
34+
}
2835
}
2936
};
3037

lib/util/identifier.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
"use strict";
22
const path = require("path");
33

4-
const looksLikeAbsolutePath = exports.looksLikeAbsolutePath = (maybeAbsolutePath) => {
4+
const looksLikeAbsolutePath = (maybeAbsolutePath) => {
55
return /^(?:[a-z]:\\|\/)/i.test(maybeAbsolutePath);
66
};
77

8+
const normalizePathSeparator = (p) => p.replace(/\\/g, "/");
9+
810
exports.makePathsRelative = (context, identifier) => {
911
return identifier
1012
.split(/([|! ])/)
11-
.map(str => looksLikeAbsolutePath(str) ? path.relative(context, str) : str)
13+
.map(str => looksLikeAbsolutePath(str) ?
14+
normalizePathSeparator(path.relative(context, str)) : str)
1215
.join("");
1316
};

0 commit comments

Comments
 (0)