refactor hop runtime helper
This commit is contained in:
parent
ba306b6f2c
commit
faf784b6ab
|
@ -204,4 +204,4 @@ exports.system = "__webpack_require__.System";
|
|||
* the shorthand for Object.prototype.hasOwnProperty
|
||||
* using of ot decreases the compiled bundle size
|
||||
*/
|
||||
exports.hasOwnProperty = "__webpack_require__.hop";
|
||||
exports.hasOwnProperty = "__webpack_require__.o";
|
||||
|
|
|
@ -16,6 +16,7 @@ const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
|
|||
const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
|
||||
const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
|
||||
const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
|
||||
const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
|
||||
const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
|
||||
const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
|
||||
|
||||
|
@ -45,6 +46,7 @@ const GLOBALS_ON_REQUIRE = [
|
|||
];
|
||||
|
||||
const TREE_DEPENDENCIES = {
|
||||
[RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
|
||||
[RuntimeGlobals.compatGetDefaultExport]: [
|
||||
RuntimeGlobals.definePropertyGetters
|
||||
],
|
||||
|
@ -113,6 +115,15 @@ class RuntimePlugin {
|
|||
);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.hasOwnProperty)
|
||||
.tap("RuntimePlugin", chunk => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new HasOwnPropertyRuntimeModule()
|
||||
);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.compatGetDefaultExport)
|
||||
.tap("RuntimePlugin", chunk => {
|
||||
|
|
|
@ -65,6 +65,10 @@ class RuntimeTemplate {
|
|||
: `function(${args}) {\n${Template.indent(body)}\n}`;
|
||||
}
|
||||
|
||||
iife(args, body) {
|
||||
return `(${this.basicFunction(args, body)})()`;
|
||||
}
|
||||
|
||||
forEach(variable, array, body) {
|
||||
return this.supportsForOf()
|
||||
? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
|
||||
|
@ -184,9 +188,12 @@ class RuntimeTemplate {
|
|||
case "statements":
|
||||
return errorStatements;
|
||||
case "promise":
|
||||
return `Promise.resolve().then(function() { ${errorStatements} })`;
|
||||
return `Promise.resolve().then(${this.basicFunction(
|
||||
"",
|
||||
errorStatements
|
||||
)})`;
|
||||
case "expression":
|
||||
return `(function() { ${errorStatements} }())`;
|
||||
return this.iife("", errorStatements);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +437,10 @@ class RuntimeTemplate {
|
|||
weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
getModuleFunction = `function() { ${header}return ${rawModule}; }`;
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${rawModule}`
|
||||
);
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.require);
|
||||
getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`;
|
||||
|
@ -438,21 +448,30 @@ class RuntimeTemplate {
|
|||
} else if (strict) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 1); }`;
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 1)`
|
||||
);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 1)`;
|
||||
}
|
||||
} else if (exportsType === "default") {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 3); }`;
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 3)`
|
||||
);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 3)`;
|
||||
}
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
getModuleFunction = `function() { ${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 7); }`;
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 7)`
|
||||
);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 7)`;
|
||||
}
|
||||
|
|
|
@ -578,7 +578,10 @@ class JavascriptModulesPlugin {
|
|||
const innerStrict = !allStrict && m.buildInfo.strict;
|
||||
const iife = innerStrict || inlinedModules.size > 1 || chunkModules;
|
||||
if (iife) {
|
||||
if (runtimeTemplate.supportsArrowFunction()) {
|
||||
if (
|
||||
!runtimeRequirements.has(RuntimeGlobals.thisAsExports) &&
|
||||
runtimeTemplate.supportsArrowFunction()
|
||||
) {
|
||||
source.add("(() => {\n");
|
||||
if (innerStrict) source.add('"use strict";\n');
|
||||
source.add(renderedModule);
|
||||
|
@ -717,24 +720,6 @@ class JavascriptModulesPlugin {
|
|||
buf.push("");
|
||||
}
|
||||
|
||||
if (runtimeRequirements.has(RuntimeGlobals.hasOwnProperty)) {
|
||||
buf.push("// the shorthand for Object.prototype.hasOwnProperty");
|
||||
if (runtimeTemplate.supportsArrowFunction()) {
|
||||
buf.push(
|
||||
`${RuntimeGlobals.hasOwnProperty} = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);`
|
||||
);
|
||||
} else {
|
||||
buf.push(`${RuntimeGlobals.hasOwnProperty} = function (obj, prop) {`);
|
||||
buf.push(
|
||||
Template.indent(
|
||||
"return Object.prototype.hasOwnProperty.call(obj, prop);"
|
||||
)
|
||||
);
|
||||
buf.push("};");
|
||||
}
|
||||
buf.push("");
|
||||
}
|
||||
|
||||
if (
|
||||
moduleFactories ||
|
||||
runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
|
||||
|
|
|
@ -21,11 +21,10 @@ class DefinePropertyGettersRuntimeModule extends HelperRuntimeModule {
|
|||
const fn = RuntimeGlobals.definePropertyGetters;
|
||||
return Template.asString([
|
||||
"// define getter functions for harmony exports",
|
||||
"var hasOwnProperty = Object.prototype.hasOwnProperty;",
|
||||
`${fn} = ${runtimeTemplate.basicFunction("exports, definition", [
|
||||
`for(var key in definition) {`,
|
||||
Template.indent([
|
||||
"if(hasOwnProperty.call(definition, key) && !hasOwnProperty.call(exports, key)) {",
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(definition, key) && !${RuntimeGlobals.hasOwnProperty}(exports, key)) {`,
|
||||
Template.indent([
|
||||
"Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });"
|
||||
]),
|
||||
|
|
|
@ -17,9 +17,9 @@ class GlobalRuntimeModule extends RuntimeModule {
|
|||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate } = this.compilation;
|
||||
return Template.asString([
|
||||
`${RuntimeGlobals.global} = (function() {`,
|
||||
Template.indent([
|
||||
`${RuntimeGlobals.global} = ${runtimeTemplate.iife("", [
|
||||
"if (typeof globalThis === 'object') return globalThis;",
|
||||
"try {",
|
||||
Template.indent(
|
||||
|
@ -38,8 +38,7 @@ class GlobalRuntimeModule extends RuntimeModule {
|
|||
// We return `undefined`, instead of nothing here, so it's
|
||||
// easier to handle this case:
|
||||
// if (!global) { … }
|
||||
]),
|
||||
"})();"
|
||||
])};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -18,7 +18,6 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
this.jsonpScript = jsonpScript;
|
||||
this.linkPreload = linkPreload;
|
||||
this.linkPrefetch = linkPrefetch;
|
||||
this.runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -179,41 +179,33 @@ class JsonpTemplatePlugin {
|
|||
: "",
|
||||
"// create error before stack unwound to get useful stacktrace later",
|
||||
"var error = new Error();",
|
||||
runtimeTemplate.supportsArrowFunction()
|
||||
? "onScriptComplete = event => {"
|
||||
: "onScriptComplete = function (event) {",
|
||||
Template.indent([
|
||||
runtimeTemplate.supportsArrowFunction()
|
||||
? "onScriptComplete = _ => _;"
|
||||
: "onScriptComplete = function() {};",
|
||||
"// avoid mem leaks in IE.",
|
||||
"script.onerror = script.onload = null;",
|
||||
"clearTimeout(timeout);",
|
||||
"var reportError = loadingEnded();",
|
||||
"if(reportError) {",
|
||||
Template.indent([
|
||||
"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
|
||||
"var realSrc = event && event.target && event.target.src;",
|
||||
"error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
||||
"error.name = 'ChunkLoadError';",
|
||||
"error.type = errorType;",
|
||||
"error.request = realSrc;",
|
||||
"reportError(error);"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"};",
|
||||
...(runtimeTemplate.supportsArrowFunction()
|
||||
? [
|
||||
`var timeout = setTimeout(_ => onScriptComplete({ type: 'timeout', target: script }), ${chunkLoadTimeout});`
|
||||
]
|
||||
: [
|
||||
"var timeout = setTimeout(function(){",
|
||||
"onScriptComplete = " +
|
||||
runtimeTemplate.basicFunction(
|
||||
"event",
|
||||
Template.asString([
|
||||
`onScriptComplete = ${runtimeTemplate.basicFunction("", "")}`,
|
||||
"// avoid mem leaks in IE.",
|
||||
"script.onerror = script.onload = null;",
|
||||
"clearTimeout(timeout);",
|
||||
"var reportError = loadingEnded();",
|
||||
"if(reportError) {",
|
||||
Template.indent([
|
||||
"onScriptComplete({ type: 'timeout', target: script });"
|
||||
"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
|
||||
"var realSrc = event && event.target && event.target.src;",
|
||||
"error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
||||
"error.name = 'ChunkLoadError';",
|
||||
"error.type = errorType;",
|
||||
"error.request = realSrc;",
|
||||
"reportError(error);"
|
||||
]),
|
||||
`}, ${chunkLoadTimeout});`
|
||||
]),
|
||||
"}"
|
||||
])
|
||||
),
|
||||
";",
|
||||
`var timeout = setTimeout(${runtimeTemplate.basicFunction(
|
||||
"",
|
||||
"onScriptComplete({ type: 'timeout', target: script })"
|
||||
)}, ${chunkLoadTimeout});`,
|
||||
"script.onerror = script.onload = onScriptComplete;"
|
||||
]);
|
||||
});
|
||||
|
@ -272,6 +264,7 @@ class JsonpTemplatePlugin {
|
|||
if (onceForChunkSet.has(chunk)) return;
|
||||
onceForChunkSet.add(chunk);
|
||||
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new JsonpChunkLoadingRuntimeModule(
|
||||
|
|
|
@ -12,7 +12,6 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
constructor(runtimeRequirements) {
|
||||
super("importScripts chunk loading", 10);
|
||||
this.runtimeRequirements = runtimeRequirements;
|
||||
this.runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -82,6 +82,7 @@ class WebWorkerTemplatePlugin {
|
|||
if (onceForChunkSet.has(chunk)) return;
|
||||
onceForChunkSet.add(chunk);
|
||||
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new ImportScriptsChunkLoadingRuntimeModule(set)
|
||||
|
|
|
@ -217,10 +217,10 @@ describe("Stats", () => {
|
|||
"comparedForEmit": false,
|
||||
"emitted": true,
|
||||
"info": Object {
|
||||
"size": 1940,
|
||||
"size": 1881,
|
||||
},
|
||||
"name": "entryB.js",
|
||||
"size": 1940,
|
||||
"size": 1881,
|
||||
},
|
||||
],
|
||||
"assetsByChunkName": Object {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,5 +9,5 @@ it("should watch for changes", function() {
|
|||
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));
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue