Skip to content

Commit 1ee3585

Browse files
committed
compilation error don't affect parent module
recover after syntax error assume es6 module on syntax error webpack#2117
1 parent bd35d4f commit 1ee3585

17 files changed

Lines changed: 156 additions & 85 deletions

File tree

lib/Compilation.js

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ Compilation.prototype.findModule = function(identifier) {
112112
return this._modules[identifier];
113113
};
114114

115-
Compilation.prototype.buildModule = function(module, thisCallback) {
116-
this.applyPlugins("build-module", module);
115+
Compilation.prototype.buildModule = function(module, optional, origin, dependencies, thisCallback) {
116+
var _this = this;
117+
_this.applyPlugins("build-module", module);
117118
if(module.building) return module.building.push(thisCallback);
118119
var building = module.building = [thisCallback];
119120

@@ -123,22 +124,28 @@ Compilation.prototype.buildModule = function(module, thisCallback) {
123124
cb(err);
124125
});
125126
}
126-
module.build(this.options, this, this.resolvers.normal, this.inputFileSystem, function(err) {
127+
module.build(_this.options, this, _this.resolvers.normal, _this.inputFileSystem, function(err) {
127128
module.errors.forEach(function(err) {
128-
this.errors.push(err);
129+
err.origin = origin;
130+
err.dependencies = dependencies;
131+
if(optional)
132+
_this.warnings.push(err);
133+
else
134+
_this.errors.push(err);
129135
}, this);
130136
module.warnings.forEach(function(err) {
131-
this.warnings.push(err);
137+
err.origin = origin;
138+
err.dependencies = dependencies;
139+
_this.warnings.push(err);
132140
}, this);
133141
module.dependencies.sort(Dependency.compare);
134142
if(err) {
135-
module.error = err;
136-
this.applyPlugins("failed-module", module);
143+
_this.applyPlugins("failed-module", module, err);
137144
return callback(err);
138145
}
139-
this.applyPlugins("succeed-module", module);
146+
_this.applyPlugins("succeed-module", module);
140147
return callback();
141-
}.bind(this));
148+
});
142149
};
143150

144151
Compilation.prototype.processModuleDependencies = function(module, callback) {
@@ -186,9 +193,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
186193
var dependencies = item[1];
187194

188195
var errorAndCallback = function errorAndCallback(err) {
189-
err.dependencies = dependencies;
190196
err.origin = module;
191-
module.dependenciesErrors.push(err);
192197
_this.errors.push(err);
193198
if(bail) {
194199
callback(err);
@@ -197,9 +202,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
197202
}
198203
};
199204
var warningAndCallback = function warningAndCallback(err) {
200-
err.dependencies = dependencies;
201205
err.origin = module;
202-
module.dependenciesWarnings.push(err);
203206
_this.warnings.push(err);
204207
callback();
205208
};
@@ -220,7 +223,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
220223
}
221224
}
222225
if(err) {
223-
return errorOrWarningAndCallback(new ModuleNotFoundError(module, err));
226+
return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies));
224227
}
225228
if(!dependentModule) {
226229
return process.nextTick(callback);
@@ -233,7 +236,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
233236
dependentModule.profile.factory = afterFactory - start;
234237
}
235238

236-
dependentModule.issuer = module.identifier();
239+
dependentModule.issuer = module;
237240
var newModule = _this.addModule(dependentModule, cacheGroup);
238241

239242
if(!newModule) { // from cache
@@ -294,7 +297,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
294297
dependentModule.addReason(module, dep);
295298
});
296299

297-
_this.buildModule(dependentModule, function(err) {
300+
_this.buildModule(dependentModule, isOptional(), module, dependencies, function(err) {
298301
if(err) {
299302
return errorOrWarningAndCallback(err);
300303
}
@@ -383,7 +386,7 @@ Compilation.prototype._addModuleChain = function process(context, dependency, on
383386

384387
onModule(module);
385388

386-
this.buildModule(module, function(err) {
389+
this.buildModule(module, false, null, null, function(err) {
387390
if(err) {
388391
return errorAndCallback(err);
389392
}
@@ -455,7 +458,7 @@ Compilation.prototype.rebuildModule = function(module, thisCallback) {
455458
});
456459
}
457460
var deps = module.dependencies.slice();
458-
this.buildModule(module, function(err) {
461+
this.buildModule(module, false, module, null, function(err) {
459462
if(err) return callback(err);
460463

461464
this.processModuleDependencies(module, function(err) {
@@ -658,10 +661,6 @@ Compilation.prototype.processDependenciesBlockForChunk = function processDepende
658661
if(d.weak) {
659662
return;
660663
}
661-
if(d.module.error) {
662-
d.module = null;
663-
return;
664-
}
665664
if(chunk.addModule(d.module)) {
666665
d.module.addChunk(chunk);
667666
this.processDependenciesBlockForChunk(d.module, chunk);

lib/Module.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function Module() {
2626
this.errors = [];
2727
this.dependenciesErrors = [];
2828
this.strict = false;
29+
this.meta = {};
2930
}
3031
module.exports = Module;
3132

lib/ModuleNotFoundError.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
function ModuleNotFoundError(module, err) {
5+
function ModuleNotFoundError(module, err, dependencies) {
66
Error.call(this);
77
Error.captureStackTrace(this, ModuleNotFoundError);
88
this.name = "ModuleNotFoundError";
99
this.message = "Module not found: " + err;
1010
this.details = err.details;
1111
this.missing = err.missing;
1212
this.module = module;
13+
this.origin = module;
14+
this.dependencies = dependencies;
1315
this.error = err;
1416
}
1517
module.exports = ModuleNotFoundError;

lib/NormalModule.js

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ function NormalModule(request, userRequest, rawRequest, loaders, resource, parse
4343
this.errors = [];
4444
this.error = null;
4545
this._source = null;
46-
this.meta = {};
4746
this.assets = {};
4847
this.built = false;
4948
this._cachedSource = null;
@@ -135,17 +134,15 @@ NormalModule.prototype.doBuild = function doBuild(options, compilation, resolver
135134
module.contextDependencies = result.contextDependencies;
136135
}
137136
if(err) {
138-
module.error = err;
139-
return callback(new ModuleBuildError(module, err));
137+
return callback(module.error = new ModuleBuildError(module, err));
140138
}
141139

142140
var resourceBuffer = result.resourceBuffer;
143141
var source = result.result[0];
144142
var sourceMap = result.result[1];
145143

146144
if(!Buffer.isBuffer(source) && typeof source !== "string") {
147-
module.error = new Error("Final loader didn't return a Buffer or String");
148-
return callback(new ModuleBuildError(module, module.error));
145+
return callback(module.error = new ModuleBuildError(module, new Error("Final loader didn't return a Buffer or String")));
149146
}
150147
source = asString(source);
151148
if(module.identifier && module.lineToLine && resourceBuffer) {
@@ -168,41 +165,54 @@ NormalModule.prototype.disconnect = function disconnect() {
168165
};
169166

170167
NormalModule.prototype.build = function build(options, compilation, resolver, fs, callback) {
171-
this.buildTimestamp = new Date().getTime();
172-
this.built = true;
173-
return this.doBuild(options, compilation, resolver, fs, function(err) {
174-
if(err) return callback(err);
175-
this.dependencies.length = 0;
176-
this.variables.length = 0;
177-
this.blocks.length = 0;
178-
this._cachedSource = null;
168+
var _this = this;
169+
_this.buildTimestamp = new Date().getTime();
170+
_this.built = true;
171+
_this._source = null;
172+
_this.error = null;
173+
return _this.doBuild(options, compilation, resolver, fs, function(err) {
174+
_this.dependencies.length = 0;
175+
_this.variables.length = 0;
176+
_this.blocks.length = 0;
177+
_this._cachedSource = null;
178+
if(err) return setError(err);
179179
if(options.module && options.module.noParse) {
180180
function testRegExp(regExp) {
181181
return typeof regExp === "string" ?
182-
this.request.indexOf(regExp) === 0 :
183-
regExp.test(this.request);
182+
_this.request.indexOf(regExp) === 0 :
183+
regExp.test(_this.request);
184184
}
185185
if(Array.isArray(options.module.noParse)) {
186-
if(options.module.noParse.some(testRegExp, this))
186+
if(options.module.noParse.some(testRegExp, _this))
187187
return callback();
188-
} else if(testRegExp.call(this, options.module.noParse)) {
188+
} else if(testRegExp.call(_this, options.module.noParse)) {
189189
return callback();
190190
}
191191
}
192192
try {
193-
this.parser.parse(this._source.source(), {
194-
current: this,
195-
module: this,
193+
_this.parser.parse(_this._source.source(), {
194+
current: _this,
195+
module: _this,
196196
compilation: compilation,
197197
options: options
198198
});
199199
} catch(e) {
200-
var source = this._source.source();
201-
this._source = null;
202-
return callback(new ModuleParseError(this, source, e));
200+
var source = _this._source.source();
201+
return setError(_this.error = new ModuleParseError(_this, source, e));
203202
}
204203
return callback();
205-
}.bind(this));
204+
});
205+
206+
function setError(err) {
207+
_this.meta = null;
208+
if(_this.error) {
209+
_this.errors.push(_this.error);
210+
_this._source = new RawSource("throw new Error(" + JSON.stringify(_this.error.message) + ");");
211+
} else {
212+
_this._source = new RawSource("throw new Error('Module build failed');");
213+
}
214+
callback();
215+
}
206216
};
207217

208218
NormalModule.prototype.source = function(dependencyTemplates, outputOptions, requestShortener) {

lib/Stats.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ Stats.prototype.toJson = function toJson(options, forToString) {
116116
text += " " + dep.loc.start.line + ":" + dep.loc.start.column + "-" +
117117
(dep.loc.start.line !== dep.loc.end.line ? dep.loc.end.line + ":" : "") + dep.loc.end.column;
118118
});
119+
var current = e.origin;
120+
while(current.issuer) {
121+
current = current.issuer;
122+
text += "\n @ " + current.readableIdentifier(requestShortener);
123+
}
119124
}
120125
return text;
121126
}
@@ -203,7 +208,9 @@ Stats.prototype.toJson = function toJson(options, forToString) {
203208
return chunk.id;
204209
}),
205210
assets: Object.keys(module.assets || {}),
206-
issuer: module.issuer,
211+
issuer: module.issuer && module.issuer.identifier(),
212+
issuerId: module.issuer && module.issuer.id,
213+
issuerName: module.issuer && module.issuer.readableIdentifier(requestShortener),
207214
profile: module.profile,
208215
failed: !!module.error,
209216
errors: module.errors && module.dependenciesErrors && (module.errors.length + module.dependenciesErrors.length),
@@ -465,17 +472,11 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
465472
function processProfile(module) {
466473
if(module.profile) {
467474
colors.normal(" ");
468-
var sum = 0,
469-
allowSum = true;
475+
var sum = 0;
470476
var path = [];
471477
var current = module;
472478
while(current.issuer) {
473-
if(!modulesByIdentifier["$" + current.issuer]) {
474-
colors.normal(" ... ->");
475-
allowSum = false;
476-
break;
477-
}
478-
path.unshift(current = modulesByIdentifier["$" + current.issuer]);
479+
path.unshift(current = current.issuer);
479480
}
480481
path.forEach(function(module) {
481482
colors.normal(" [");
@@ -495,10 +496,8 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
495496
coloredTime(time);
496497
sum += time;
497498
});
498-
if(allowSum) {
499-
colors.normal(" = ");
500-
coloredTime(sum);
501-
}
499+
colors.normal(" = ");
500+
coloredTime(sum);
502501
newline();
503502
}
504503
}

lib/dependencies/HarmonyExportImportedSpecifierDependency.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
6363
content = "/* unused harmony reexport " + dep.name + " */\n";
6464
} else if(!active) { // we want to reexport something but another exports overrides this one
6565
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */\n";
66-
} else if(dep.name && dep.id === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule)) { // we want to reexport the default export from a non-hamory module
66+
} else if(dep.name && dep.id === "default" && !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule))) { // we want to reexport the default export from a non-hamory module
6767
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), null) + "\n";
6868
} else if(dep.name && dep.id) { // we want to reexport a key as new key
6969
var idUsed = importedModule && importedModule.isUsed(dep.id);
@@ -72,7 +72,7 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
7272
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), "") + "\n";
7373
} else if(Array.isArray(dep.originModule.usedExports)) { // we know which exports are used
7474
activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
75-
var importIsHarmony = importedModule && importedModule.meta.harmonyModule;
75+
var importIsHarmony = importedModule && (!importedModule.meta || importedModule.meta.harmonyModule);
7676
var importActiveExports = importedModule && HarmonyModulesHelpers.getActiveExports(importedModule);
7777
var items = dep.originModule.usedExports.map(function(id) {
7878
if(id === "default") return;

lib/dependencies/HarmonyImportDependency.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ HarmonyImportDependency.prototype.getReference = function() {
2525

2626
HarmonyImportDependency.prototype.updateHash = function updateHash(hash) {
2727
ModuleDependency.prototype.updateHash.call(this, hash);
28-
hash.update((this.module && this.module.meta && this.module.meta.harmonyModule) + "");
28+
hash.update((this.module && (!this.module.meta || this.module.meta.harmonyModule)) + "");
2929
};
3030

3131
HarmonyImportDependency.makeStatement = function(declare, dep, outputOptions, requestShortener) {

lib/dependencies/HarmonyImportSpecifierDependency.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ HarmonyImportSpecifierDependency.prototype.updateHash = function(hash) {
4747
hash.update((importedModule && this.id) + "");
4848
hash.update((importedModule && this.importedVar) + "");
4949
hash.update((importedModule && this.id && importedModule.isUsed(this.id)) + "");
50-
hash.update((importedModule && importedModule.meta && importedModule.meta.harmonyModule) + "");
50+
hash.update((importedModule && (!importedModule.meta || importedModule.meta.harmonyModule)) + "");
5151
hash.update((importedModule && (importedModule.used + JSON.stringify(importedModule.usedExports))) + "");
5252
};
5353

@@ -56,7 +56,7 @@ HarmonyImportSpecifierDependency.Template = function HarmonyImportSpecifierDepen
5656
HarmonyImportSpecifierDependency.Template.prototype.apply = function(dep, source) {
5757
var content;
5858
var importedModule = dep.importDependency.module;
59-
var defaultImport = dep.id === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule);
59+
var defaultImport = dep.id === "default" && !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule));
6060
if(defaultImport) {
6161
content = dep.importedVar + "_default.a";
6262
} else if(dep.id) {

test/HotTestCases.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ describe("HotTestCases", function() {
7777
var jsonStats = stats.toJson({
7878
errorDetails: true
7979
});
80-
if(checkArrayExpectation(testDirectory, jsonStats, "error", "Error", done)) return;
81-
if(checkArrayExpectation(testDirectory, jsonStats, "warning", "Warning", done)) return;
80+
if(checkArrayExpectation(testDirectory, jsonStats, "error", "errors" + options.updateIndex, "Error", done)) return;
81+
if(checkArrayExpectation(testDirectory, jsonStats, "warning", "warnings" + options.updateIndex, "Warning", done)) return;
8282
if(callback) callback();
8383
})
8484
}

test/checkArrayExpectation.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
var fs = require("fs");
22
var path = require("path");
33

4-
module.exports = function checkArrayExpectation(testDirectory, object, kind, upperCaseKind, done) {
4+
module.exports = function checkArrayExpectation(testDirectory, object, kind, filename, upperCaseKind, done) {
5+
if(!done) {
6+
done = upperCaseKind;
7+
upperCaseKind = filename;
8+
filename = kind + "s";
9+
}
510
var array = object[kind + "s"].slice().sort();
611
if(kind === "warning") array = array.filter(function(item) {
712
return !/from UglifyJs/.test(item);
813
});
9-
if(fs.existsSync(path.join(testDirectory, kind + "s.js"))) {
10-
var expected = require(path.join(testDirectory, kind + "s.js"));
14+
if(fs.existsSync(path.join(testDirectory, filename + ".js"))) {
15+
var expected = require(path.join(testDirectory, filename + ".js"));
1116
if(expected.length < array.length)
1217
return done(new Error("More " + kind + "s while compiling than expected:\n\n" + array.join("\n\n"))), true;
1318
else if(expected.length > array.length)

0 commit comments

Comments
 (0)