Merge pull request #10069 from smelukov/optimize-webpack-runtime-size

optimize webpack runtime size
This commit is contained in:
Tobias Koppers 2019-12-03 16:57:56 +01:00 committed by GitHub
commit 157c457241
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 470 additions and 382 deletions

View File

@ -545,7 +545,7 @@ function webpackContext(req) {
${returnModuleObject} ${returnModuleObject}
} }
function webpackContextResolve(req) { function webpackContextResolve(req) {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -584,7 +584,7 @@ function webpackContext(req) {
${returnModuleObject} ${returnModuleObject}
} }
function webpackContextResolve(req) { function webpackContextResolve(req) {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -632,7 +632,7 @@ function webpackAsyncContextResolve(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent // Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools // uncaught exception popping up in devtools
return Promise.resolve().then(${arrow ? "() =>" : "function()"} { return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -640,9 +640,9 @@ function webpackAsyncContextResolve(req) {
return map[req]; return map[req];
}); });
} }
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
return Object.keys(map); "Object.keys(map)"
}; )};
webpackAsyncContext.resolve = webpackAsyncContextResolve; webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)}; webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`; module.exports = webpackAsyncContext;`;
@ -676,7 +676,7 @@ function webpackAsyncContextResolve(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent // Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools // uncaught exception popping up in devtools
return Promise.resolve().then(${arrow ? "() =>" : "function()"} { return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -684,9 +684,9 @@ function webpackAsyncContextResolve(req) {
return map[req]; return map[req];
}); });
} }
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
return Object.keys(map); "Object.keys(map)"
}; )};
webpackAsyncContext.resolve = webpackAsyncContextResolve; webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)}; webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`; module.exports = webpackAsyncContext;`;
@ -726,7 +726,7 @@ function webpackAsyncContext(req) {
} }
function webpackAsyncContextResolve(req) { function webpackAsyncContextResolve(req) {
return ${promise}.then(${arrow ? "() =>" : "function()"} { return ${promise}.then(${arrow ? "() =>" : "function()"} {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -734,9 +734,9 @@ function webpackAsyncContextResolve(req) {
return map[req]; return map[req];
}); });
} }
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
return Object.keys(map); "Object.keys(map)"
}; )};
webpackAsyncContext.resolve = webpackAsyncContextResolve; webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)}; webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`; module.exports = webpackAsyncContext;`;
@ -821,7 +821,7 @@ module.exports = webpackAsyncContext;`;
? `${shortMode ? "" : ""} ? `${shortMode ? "" : ""}
function webpackAsyncContext(req) { function webpackAsyncContext(req) {
return Promise.resolve().then(${arrow ? "() =>" : "function()"} { return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
throw e; throw e;
@ -832,7 +832,7 @@ function webpackAsyncContext(req) {
}); });
}` }`
: `function webpackAsyncContext(req) { : `function webpackAsyncContext(req) {
if(!Object.prototype.hasOwnProperty.call(map, req)) { if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
return Promise.resolve().then(${arrow ? "() =>" : "function()"} { return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
var e = new Error("Cannot find module '" + req + "'"); var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND'; e.code = 'MODULE_NOT_FOUND';
@ -848,9 +848,9 @@ function webpackAsyncContext(req) {
return `var map = ${JSON.stringify(map, null, "\t")}; return `var map = ${JSON.stringify(map, null, "\t")};
${webpackAsyncContext} ${webpackAsyncContext}
webpackAsyncContext.keys = function webpackAsyncContextKeys() { webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
return Object.keys(map); "Object.keys(map)"
}; )};
webpackAsyncContext.id = ${JSON.stringify(id)}; webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`; module.exports = webpackAsyncContext;`;
} }
@ -962,6 +962,7 @@ module.exports = webpackEmptyAsyncContext;`;
this.blocks.map(b => b.dependencies[0]) this.blocks.map(b => b.dependencies[0])
)); ));
set.push(RuntimeGlobals.module); set.push(RuntimeGlobals.module);
set.push(RuntimeGlobals.hasOwnProperty);
if (allDeps.length > 0) { if (allDeps.length > 0) {
const asyncMode = this.options.mode; const asyncMode = this.options.mode;
set.push(RuntimeGlobals.require); set.push(RuntimeGlobals.require);

View File

@ -199,3 +199,9 @@ exports.amdOptions = "__webpack_require__.amdO";
* the System polyfill object * the System polyfill object
*/ */
exports.system = "__webpack_require__.System"; exports.system = "__webpack_require__.System";
/**
* the shorthand for Object.prototype.hasOwnProperty
* using of ot decreases the compiled bundle size
*/
exports.hasOwnProperty = "__webpack_require__.o";

View File

@ -16,6 +16,7 @@ const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule"); const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule"); const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule"); const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule"); const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule"); const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
@ -45,6 +46,7 @@ const GLOBALS_ON_REQUIRE = [
]; ];
const TREE_DEPENDENCIES = { const TREE_DEPENDENCIES = {
[RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
[RuntimeGlobals.compatGetDefaultExport]: [ [RuntimeGlobals.compatGetDefaultExport]: [
RuntimeGlobals.definePropertyGetters RuntimeGlobals.definePropertyGetters
], ],
@ -113,6 +115,15 @@ class RuntimePlugin {
); );
return true; return true;
}); });
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.hasOwnProperty)
.tap("RuntimePlugin", chunk => {
compilation.addRuntimeModule(
chunk,
new HasOwnPropertyRuntimeModule()
);
return true;
});
compilation.hooks.runtimeRequirementInTree compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.compatGetDefaultExport) .for(RuntimeGlobals.compatGetDefaultExport)
.tap("RuntimePlugin", chunk => { .tap("RuntimePlugin", chunk => {

View File

@ -65,6 +65,10 @@ class RuntimeTemplate {
: `function(${args}) {\n${Template.indent(body)}\n}`; : `function(${args}) {\n${Template.indent(body)}\n}`;
} }
iife(args, body) {
return `(${this.basicFunction(args, body)})()`;
}
forEach(variable, array, body) { forEach(variable, array, body) {
return this.supportsForOf() return this.supportsForOf()
? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}` ? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
@ -184,9 +188,12 @@ class RuntimeTemplate {
case "statements": case "statements":
return errorStatements; return errorStatements;
case "promise": case "promise":
return `Promise.resolve().then(function() { ${errorStatements} })`; return `Promise.resolve().then(${this.basicFunction(
"",
errorStatements
)})`;
case "expression": case "expression":
return `(function() { ${errorStatements} }())`; return this.iife("", errorStatements);
} }
} }
@ -430,7 +437,10 @@ class RuntimeTemplate {
weak, weak,
runtimeRequirements runtimeRequirements
}); });
getModuleFunction = `function() { ${header}return ${rawModule}; }`; getModuleFunction = this.basicFunction(
"",
`${header}return ${rawModule};`
);
} else { } else {
runtimeRequirements.add(RuntimeGlobals.require); runtimeRequirements.add(RuntimeGlobals.require);
getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`; getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`;
@ -438,21 +448,30 @@ class RuntimeTemplate {
} else if (strict) { } else if (strict) {
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
if (header) { if (header) {
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 1); }`; const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 1)`;
getModuleFunction = header
? this.basicFunction("", `${header}return ${returnExpression};`)
: this.returningFunction(returnExpression);
} else { } else {
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 1)`; getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 1)`;
} }
} else if (exportsType === "default") { } else if (exportsType === "default") {
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
if (header) { if (header) {
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 3); }`; const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 3)`;
getModuleFunction = header
? this.basicFunction("", `${header}return ${returnExpression};`)
: this.returningFunction(returnExpression);
} else { } else {
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 3)`; getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 3)`;
} }
} else { } else {
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
if (header) { if (header) {
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 7); }`; const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 7)`;
getModuleFunction = header
? this.basicFunction("", `${header}return ${returnExpression};`)
: this.returningFunction(returnExpression);
} else { } else {
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 7)`; getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 7)`;
} }

View File

@ -892,8 +892,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
runtimeRequirements.add(RuntimeGlobals.exports); runtimeRequirements.add(RuntimeGlobals.exports);
runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
return `if(Object.prototype.hasOwnProperty.call(${name}, ${JSON.stringify( return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify(
valueKey[0] valueKey[0]
)})) ${ )})) ${
RuntimeGlobals.definePropertyGetters RuntimeGlobals.definePropertyGetters

View File

@ -496,7 +496,7 @@ class JavascriptModulesPlugin {
let source = new ConcatSource(); let source = new ConcatSource();
let prefix; let prefix;
if (iife) { if (iife) {
if (runtimeTemplate.supportsConst()) { if (runtimeTemplate.supportsArrowFunction()) {
source.add("/******/ (() => { // webpackBootstrap\n"); source.add("/******/ (() => { // webpackBootstrap\n");
} else { } else {
source.add("/******/ (function() { // webpackBootstrap\n"); source.add("/******/ (function() { // webpackBootstrap\n");
@ -578,10 +578,17 @@ class JavascriptModulesPlugin {
const innerStrict = !allStrict && m.buildInfo.strict; const innerStrict = !allStrict && m.buildInfo.strict;
const iife = innerStrict || inlinedModules.size > 1 || chunkModules; const iife = innerStrict || inlinedModules.size > 1 || chunkModules;
if (iife) { if (iife) {
source.add("!function() {\n"); if (runtimeTemplate.supportsArrowFunction()) {
if (innerStrict) source.add('"use strict";\n'); source.add("(() => {\n");
source.add(renderedModule); if (innerStrict) source.add('"use strict";\n');
source.add("\n}();\n"); source.add(renderedModule);
source.add("\n})();\n\n");
} else {
source.add("!function() {\n");
if (innerStrict) source.add('"use strict";\n');
source.add(renderedModule);
source.add("\n}();\n");
}
} else { } else {
source.add(renderedModule); source.add(renderedModule);
source.add("\n"); source.add("\n");

View File

@ -60,6 +60,7 @@ class NodeTemplatePlugin {
if (onceForChunkSet.has(chunk)) return; if (onceForChunkSet.has(chunk)) return;
onceForChunkSet.add(chunk); onceForChunkSet.add(chunk);
set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.moduleFactoriesAddOnly);
set.add(RuntimeGlobals.hasOwnProperty);
compilation.addRuntimeModule(chunk, new ChunkLoadingRuntimeModule(set)); compilation.addRuntimeModule(chunk, new ChunkLoadingRuntimeModule(set));
}; };

View File

@ -77,7 +77,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;", "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([ Template.indent([
`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
]), ]),
@ -148,7 +148,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
"var runtime = update.runtime;", "var runtime = update.runtime;",
"for(var moduleId in updatedModules) {", "for(var moduleId in updatedModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(updatedModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
Template.indent([ Template.indent([
`currentUpdate[moduleId] = updatedModules[moduleId];`, `currentUpdate[moduleId] = updatedModules[moduleId];`,
"if(updatedModulesList) updatedModulesList.push(moduleId);" "if(updatedModulesList) updatedModulesList.push(moduleId);"

View File

@ -62,7 +62,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;", "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([ Template.indent([
`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
]), ]),
@ -107,7 +107,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
"var runtime = update.runtime;", "var runtime = update.runtime;",
"for(var moduleId in updatedModules) {", "for(var moduleId in updatedModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(updatedModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
Template.indent([ Template.indent([
`currentUpdate[moduleId] = updatedModules[moduleId];`, `currentUpdate[moduleId] = updatedModules[moduleId];`,
"if(updatedModulesList) updatedModulesList.push(moduleId);" "if(updatedModulesList) updatedModulesList.push(moduleId);"

View File

@ -21,11 +21,10 @@ class DefinePropertyGettersRuntimeModule extends HelperRuntimeModule {
const fn = RuntimeGlobals.definePropertyGetters; const fn = RuntimeGlobals.definePropertyGetters;
return Template.asString([ return Template.asString([
"// define getter functions for harmony exports", "// define getter functions for harmony exports",
"var hasOwnProperty = Object.prototype.hasOwnProperty;",
`${fn} = ${runtimeTemplate.basicFunction("exports, definition", [ `${fn} = ${runtimeTemplate.basicFunction("exports, definition", [
`for(var key in definition) {`, `for(var key in definition) {`,
Template.indent([ Template.indent([
"if(hasOwnProperty.call(definition, key) && !hasOwnProperty.call(exports, key)) {", `if(${RuntimeGlobals.hasOwnProperty}(definition, key) && !${RuntimeGlobals.hasOwnProperty}(exports, key)) {`,
Template.indent([ Template.indent([
"Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });" "Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });"
]), ]),

View File

@ -0,0 +1,32 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Sergey Melyukov @smelukov
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
class HasOwnPropertyRuntimeModule extends RuntimeModule {
constructor() {
super("hasOwnProperty shorthand");
}
/**
* @returns {string} runtime code
*/
generate() {
const { runtimeTemplate } = this.compilation;
return Template.asString([
`${RuntimeGlobals.hasOwnProperty} = ${runtimeTemplate.returningFunction(
"Object.prototype.hasOwnProperty.call(obj, prop)",
"obj, prop"
)}`
]);
}
}
module.exports = HasOwnPropertyRuntimeModule;

View File

@ -112,7 +112,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
hasJsMatcher !== false hasJsMatcher !== false
? Template.indent([ ? Template.indent([
"// JSONP chunk loading for javascript", "// JSONP chunk loading for javascript",
`var installedChunkData = Object.prototype.hasOwnProperty.call(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
'if(installedChunkData !== 0) { // 0 means "already installed".', 'if(installedChunkData !== 0) { // 0 means "already installed".',
Template.indent([ Template.indent([
"", "",
@ -141,7 +141,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
`var loadingEnded = ${runtimeTemplate.basicFunction( `var loadingEnded = ${runtimeTemplate.basicFunction(
"", "",
[ [
"if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId)) {", `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
Template.indent([ Template.indent([
"installedChunkData = installedChunks[chunkId];", "installedChunkData = installedChunks[chunkId];",
"if(installedChunkData !== 0) installedChunks[chunkId] = undefined;", "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
@ -173,7 +173,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
"chunkId", "chunkId",
"chunkPreloadData", "chunkPreloadData",
[ [
"if(!Object.prototype.hasOwnProperty.call(installedChunks, chunkId) || installedChunks[chunkId] === undefined) {", `if(!${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) {`,
Template.indent([ Template.indent([
"installedChunks[chunkId] = null;", "installedChunks[chunkId] = null;",
linkPreload.call("", chunk), linkPreload.call("", chunk),
@ -202,7 +202,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
? Template.asString([ ? Template.asString([
"function prefetchChunk(chunkId) {", "function prefetchChunk(chunkId) {",
Template.indent([ Template.indent([
"if(!Object.prototype.hasOwnProperty.call(installedChunks, chunkId) || installedChunks[chunkId] === undefined) {", `if(!${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) {`,
Template.indent([ Template.indent([
"installedChunks[chunkId] = null;", "installedChunks[chunkId] = null;",
linkPrefetch.call("", chunk), linkPrefetch.call("", chunk),
@ -251,7 +251,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
[ [
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([ Template.indent([
"currentUpdate[moduleId] = moreModules[moduleId];", "currentUpdate[moduleId] = moreModules[moduleId];",
"if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);" "if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);"
@ -310,7 +310,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
"currentUpdateRuntime = [];", "currentUpdateRuntime = [];",
"currentUpdatedModulesList = updatedModulesList;", "currentUpdatedModulesList = updatedModulesList;",
runtimeTemplate.forEach("chunkId", "chunkIds", [ runtimeTemplate.forEach("chunkId", "chunkIds", [
"if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId] !== undefined) {", `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId] !== undefined) {`,
Template.indent(["promises.push(loadUpdateChunk(chunkId));"]), Template.indent(["promises.push(loadUpdateChunk(chunkId));"]),
"}", "}",
"currentUpdateChunks[chunkId] = true;" "currentUpdateChunks[chunkId] = true;"
@ -414,7 +414,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
"for(;i < chunkIds.length; i++) {", "for(;i < chunkIds.length; i++) {",
Template.indent([ Template.indent([
"chunkId = chunkIds[i];", "chunkId = chunkIds[i];",
"if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {", `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
Template.indent("resolves.push(installedChunks[chunkId][0]);"), Template.indent("resolves.push(installedChunks[chunkId][0]);"),
"}", "}",
"installedChunks[chunkId] = 0;" "installedChunks[chunkId] = 0;"
@ -422,7 +422,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
"}", "}",
"for(moduleId in moreModules) {", "for(moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent( Template.indent(
`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
), ),

View File

@ -145,6 +145,7 @@ class JsonpTemplatePlugin {
linkPreload, linkPreload,
linkPrefetch linkPrefetch
} = JsonpTemplatePlugin.getCompilationHooks(compilation); } = JsonpTemplatePlugin.getCompilationHooks(compilation);
const { runtimeTemplate } = compilation;
jsonpScript.tap("JsonpTemplatePlugin", (_, chunk, hash) => { jsonpScript.tap("JsonpTemplatePlugin", (_, chunk, hash) => {
const { const {
@ -178,31 +179,33 @@ class JsonpTemplatePlugin {
: "", : "",
"// create error before stack unwound to get useful stacktrace later", "// create error before stack unwound to get useful stacktrace later",
"var error = new Error();", "var error = new Error();",
"onScriptComplete = function (event) {", "onScriptComplete = " +
Template.indent([ runtimeTemplate.basicFunction(
"onScriptComplete = function() {};", "event",
"// avoid mem leaks in IE.", Template.asString([
"script.onerror = script.onload = null;", `onScriptComplete = ${runtimeTemplate.basicFunction("", "")}`,
"clearTimeout(timeout);", "// avoid mem leaks in IE.",
"var reportError = loadingEnded();", "script.onerror = script.onload = null;",
"if(reportError) {", "clearTimeout(timeout);",
Template.indent([ "var reportError = loadingEnded();",
"var errorType = event && (event.type === 'load' ? 'missing' : event.type);", "if(reportError) {",
"var realSrc = event && event.target && event.target.src;", Template.indent([
"error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';", "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
"error.name = 'ChunkLoadError';", "var realSrc = event && event.target && event.target.src;",
"error.type = errorType;", "error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
"error.request = realSrc;", "error.name = 'ChunkLoadError';",
"reportError(error);" "error.type = errorType;",
]), "error.request = realSrc;",
"}" "reportError(error);"
]), ]),
"};", "}"
"var timeout = setTimeout(function(){", ])
Template.indent([ ),
"onScriptComplete({ type: 'timeout', target: script });" ";",
]), `var timeout = setTimeout(${runtimeTemplate.basicFunction(
`}, ${chunkLoadTimeout});`, "",
"onScriptComplete({ type: 'timeout', target: script })"
)}, ${chunkLoadTimeout});`,
"script.onerror = script.onload = onScriptComplete;" "script.onerror = script.onload = onScriptComplete;"
]); ]);
}); });
@ -261,6 +264,7 @@ class JsonpTemplatePlugin {
if (onceForChunkSet.has(chunk)) return; if (onceForChunkSet.has(chunk)) return;
onceForChunkSet.add(chunk); onceForChunkSet.add(chunk);
set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.moduleFactoriesAddOnly);
set.add(RuntimeGlobals.hasOwnProperty);
compilation.addRuntimeModule( compilation.addRuntimeModule(
chunk, chunk,
new JsonpChunkLoadingRuntimeModule( new JsonpChunkLoadingRuntimeModule(

View File

@ -57,7 +57,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
Template.indent([ Template.indent([
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent( Template.indent(
`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
), ),
@ -95,7 +95,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
Template.indent([ Template.indent([
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent([ Template.indent([
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([ Template.indent([
"currentUpdate[moduleId] = moreModules[moduleId];", "currentUpdate[moduleId] = moreModules[moduleId];",
"if(updatedModulesList) updatedModulesList.push(moduleId);" "if(updatedModulesList) updatedModulesList.push(moduleId);"

View File

@ -82,6 +82,7 @@ class WebWorkerTemplatePlugin {
if (onceForChunkSet.has(chunk)) return; if (onceForChunkSet.has(chunk)) return;
onceForChunkSet.add(chunk); onceForChunkSet.add(chunk);
set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.moduleFactoriesAddOnly);
set.add(RuntimeGlobals.hasOwnProperty);
compilation.addRuntimeModule( compilation.addRuntimeModule(
chunk, chunk,
new ImportScriptsChunkLoadingRuntimeModule(set) new ImportScriptsChunkLoadingRuntimeModule(set)

View File

@ -217,10 +217,10 @@ describe("Stats", () => {
"comparedForEmit": false, "comparedForEmit": false,
"emitted": true, "emitted": true,
"info": Object { "info": Object {
"size": 2036, "size": 1881,
}, },
"name": "entryB.js", "name": "entryB.js",
"size": 2036, "size": 1881,
}, },
], ],
"assetsByChunkName": Object { "assetsByChunkName": Object {

File diff suppressed because it is too large Load Diff

View File

@ -9,5 +9,5 @@ it("should watch for changes", function() {
expect(require("./foo/" + WATCH_STEP)).toBe('This should be working.' + WATCH_STEP); expect(require("./foo/" + WATCH_STEP)).toBe('This should be working.' + WATCH_STEP);
} }
expect(STATS_JSON.modules.length).toBe(6 + Number(WATCH_STEP)); expect(STATS_JSON.modules.length).toBe(7 + Number(WATCH_STEP));
}); });