Skip to content

Commit bf1f114

Browse files
committed
Chunk loading error handling
fixes webpack#692 fixes webpack#758 fixes webpack#686 fixes webpack#785
1 parent 383fd71 commit bf1f114

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

lib/JsonpMainTemplatePlugin.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ JsonpMainTemplatePlugin.prototype.apply = function(mainTemplate) {
3131
var chunkFilename = this.outputOptions.chunkFilename || "[id]." + filename;
3232
var chunkMaps = chunk.getChunkMaps();
3333
var crossOriginLoading = this.outputOptions.crossOriginLoading;
34+
var chunkLoadTimeout = this.outputOptions.chunkLoadTimeout || 120000;
3435
return this.asString([
3536
"if(installedChunks[chunkId] === 0)",
3637
this.indent([
@@ -49,6 +50,7 @@ JsonpMainTemplatePlugin.prototype.apply = function(mainTemplate) {
4950
"script.type = 'text/javascript';",
5051
"script.charset = 'utf-8';",
5152
"script.async = true;",
53+
"script.timeout = " + chunkLoadTimeout + ";",
5254
crossOriginLoading ? "script.crossOrigin = '" + crossOriginLoading + "';" : "",
5355
"script.src = " + this.requireFn + ".p + " +
5456
this.applyPluginsWaterfall("asset-path", JSON.stringify(chunkFilename), {
@@ -70,6 +72,22 @@ JsonpMainTemplatePlugin.prototype.apply = function(mainTemplate) {
7072
name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \""
7173
}
7274
}) + ";",
75+
"var timeout = setTimeout(onScriptComplete, " + chunkLoadTimeout + ");",
76+
"script.onerror = script.onload = onScriptComplete;",
77+
"function onScriptComplete() {",
78+
this.indent([
79+
"// avoid mem leaks in IE.",
80+
"script.onerror = script.onload = null;",
81+
"clearTimeout(timeout);",
82+
"var chunk = installedChunks[chunkId];",
83+
"if(chunk !== 0) {",
84+
this.indent([
85+
"if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));",
86+
"installedChunks[chunkId] = undefined;"
87+
]),
88+
"}"
89+
]),
90+
"};",
7391
"head.appendChild(script);",
7492
"",
7593
"var promise = new Promise(function(resolve, reject) {",

test/browsertest/lib/index.web.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,25 @@ describe("main", function() {
9292
});
9393
});
9494

95+
describe("chunk error handling", function() {
96+
it("should be able to handle chunk loading errors and try again", function(done) {
97+
var old = __webpack_public_path__;
98+
__webpack_public_path__ += "wrong/";
99+
System.import("./three").then(function() {
100+
done(new Error("Chunk shouldn't be loaded"));
101+
}).catch(function(err) {
102+
err.should.be.instanceOf(Error);
103+
__webpack_public_path__ = old;
104+
System.import("./three").then(function(three) {
105+
three.should.be.eql(3);
106+
done();
107+
}).catch(function(err) {
108+
done(new Error("Shouldn't result in an chunk loading error"));
109+
});
110+
});
111+
});
112+
});
113+
95114
var testCasesContext = require.context("../../cases", true, /^\.\/[^\/_]+\/[^\/_]+\/index$/);
96115
var testCasesMap = testCasesContext.keys().map(function(key) {
97116
return key.substring(2, key.length - "/index".length).split("/");

test/browsertest/lib/three.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 3;

0 commit comments

Comments
 (0)