Skip to content

Commit af52c8f

Browse files
authored
Merge pull request #12174 from webpack/bugfix/bootstrap
fix startup logic preventing inlining entry modules
2 parents edae614 + f70aa0e commit af52c8f

25 files changed

+658
-492
lines changed

lib/MainTemplate.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class MainTemplate {
9191
beforeStartup: {
9292
tap: () => {
9393
throw new Error(
94-
"MainTemplate.hooks.beforeStartup has been removed (use RuntimeGlobals.startup instead)"
94+
"MainTemplate.hooks.beforeStartup has been removed (use RuntimeGlobals.startupOnlyBefore instead)"
9595
);
9696
}
9797
},
@@ -105,7 +105,7 @@ class MainTemplate {
105105
afterStartup: {
106106
tap: () => {
107107
throw new Error(
108-
"MainTemplate.hooks.afterStartup has been removed (use RuntimeGlobals.startup instead)"
108+
"MainTemplate.hooks.afterStartup has been removed (use RuntimeGlobals.startupOnlyAfter instead)"
109109
);
110110
}
111111
},

lib/ModuleInfoHeaderPlugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class ModuleInfoHeaderPlugin {
191191
const req = module.readableIdentifier(requestShortener);
192192
const reqStr = req.replace(/\*\//g, "*_/");
193193
const reqStrStar = "*".repeat(reqStr.length);
194-
const headerStr = `/*!****${reqStrStar}****!*\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
194+
const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
195195
header = new RawSource(headerStr);
196196
cacheEntry.header = header;
197197
}

lib/RuntimeGlobals.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,20 @@ exports.getChunkUpdateScriptFilename = "__webpack_require__.hu";
194194
exports.startup = "__webpack_require__.x";
195195

196196
/**
197-
* startup signal from runtime
197+
* creating a default startup function with the entry modules
198198
*/
199199
exports.startupNoDefault = "__webpack_require__.x (no default handler)";
200200

201+
/**
202+
* startup signal from runtime but only used to add logic after the startup
203+
*/
204+
exports.startupOnlyAfter = "__webpack_require__.x (only after)";
205+
206+
/**
207+
* startup signal from runtime but only used to add sync logic before the startup
208+
*/
209+
exports.startupOnlyBefore = "__webpack_require__.x (only before)";
210+
201211
/**
202212
* method to startup an entrypoint with needed chunks.
203213
* Signature: (moduleId: Id, chunkIds: Id[]) => any.

lib/RuntimeModule.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,24 @@ class RuntimeModule extends Module {
185185
}
186186
}
187187

188+
/**
189+
* Runtime modules without any dependencies to other runtime modules
190+
*/
191+
RuntimeModule.STAGE_NORMAL = 0;
192+
193+
/**
194+
* Runtime modules with simple dependencies on other runtime modules
195+
*/
196+
RuntimeModule.STAGE_BASIC = 5;
197+
198+
/**
199+
* Runtime modules which attach to handlers of other runtime modules
200+
*/
201+
RuntimeModule.STAGE_ATTACH = 10;
202+
203+
/**
204+
* Runtime modules which trigger actions on bootstrap
205+
*/
206+
RuntimeModule.STAGE_TRIGGER = 20;
207+
188208
module.exports = RuntimeModule;

lib/RuntimeTemplate.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ class RuntimeTemplate {
113113
: `function(${args}) {\n${Template.indent(body)}\n}`;
114114
}
115115

116+
emptyFunction() {
117+
return this.supportsArrowFunction() ? "x => {}" : "function() {}";
118+
}
119+
116120
destructureArray(items, value) {
117121
return this.supportsDestructuring()
118122
? `var [${items.join(", ")}] = ${value};`

lib/hmr/HotModuleReplacementRuntimeModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const Template = require("../Template");
1111

1212
class HotModuleReplacementRuntimeModule extends RuntimeModule {
1313
constructor() {
14-
super("hot module replacement", 5);
14+
super("hot module replacement", RuntimeModule.STAGE_BASIC);
1515
}
1616
/**
1717
* @returns {string} runtime code

lib/javascript/JavascriptModulesPlugin.js

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,17 @@ class JavascriptModulesPlugin {
630630
}
631631
}
632632
if (inlinedModules) {
633+
if (bootstrap.beforeStartup.length > 0) {
634+
const beforeStartup = Template.asString(bootstrap.beforeStartup) + "\n";
635+
source.add(
636+
new PrefixSource(
637+
prefix,
638+
useSourceMap
639+
? new OriginalSource(beforeStartup, "webpack/before-startup")
640+
: new RawSource(beforeStartup)
641+
)
642+
);
643+
}
633644
for (const m of inlinedModules) {
634645
const renderedModule = this.renderModule(
635646
m,
@@ -658,8 +669,24 @@ class JavascriptModulesPlugin {
658669
}
659670
}
660671
}
672+
if (bootstrap.afterStartup.length > 0) {
673+
const afterStartup = Template.asString(bootstrap.afterStartup) + "\n";
674+
source.add(
675+
new PrefixSource(
676+
prefix,
677+
useSourceMap
678+
? new OriginalSource(afterStartup, "webpack/after-startup")
679+
: new RawSource(afterStartup)
680+
)
681+
);
682+
}
661683
} else {
662-
const startup = Template.asString(bootstrap.startup) + "\n";
684+
const startup =
685+
Template.asString([
686+
...bootstrap.beforeStartup,
687+
...bootstrap.startup,
688+
...bootstrap.afterStartup
689+
]) + "\n";
663690
source.add(
664691
new PrefixSource(
665692
prefix,
@@ -718,7 +745,7 @@ class JavascriptModulesPlugin {
718745
/**
719746
* @param {RenderBootstrapContext} renderContext options object
720747
* @param {CompilationHooks} hooks hooks
721-
* @returns {{ header: string[], startup: string[], allowInlineStartup: boolean }} the generated source of the bootstrap code
748+
* @returns {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} the generated source of the bootstrap code
722749
*/
723750
renderBootstrap(renderContext, hooks) {
724751
const { chunkGraph, moduleGraph, chunk, runtimeTemplate } = renderContext;
@@ -751,12 +778,13 @@ class JavascriptModulesPlugin {
751778

752779
const result = {
753780
header: [],
781+
beforeStartup: [],
754782
startup: [],
783+
afterStartup: [],
755784
allowInlineStartup: true
756785
};
757786

758-
let buf = result.header;
759-
let startup = result.startup;
787+
let { header: buf, startup, beforeStartup, afterStartup } = result;
760788

761789
if (result.allowInlineStartup && moduleFactories) {
762790
startup.push(
@@ -889,40 +917,68 @@ class JavascriptModulesPlugin {
889917
buf2.push(`__webpack_modules__[${moduleIdExpr}]();`);
890918
}
891919
}
892-
if (runtimeRequirements.has(RuntimeGlobals.startup)) {
920+
if (
921+
runtimeRequirements.has(RuntimeGlobals.startup) ||
922+
((returnExportsFromRuntime ||
923+
runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) &&
924+
runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter))
925+
) {
893926
result.allowInlineStartup = false;
927+
buf.push("// the startup function");
894928
buf.push(
895-
Template.asString([
896-
"// the startup function",
897-
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
898-
"",
899-
buf2
900-
)};`
901-
])
929+
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
930+
"",
931+
buf2
932+
)};`
902933
);
903934
buf.push("");
904935
startup.push("// run startup");
905936
startup.push(`return ${RuntimeGlobals.startup}();`);
906-
} else {
907-
startup.push(
908-
Template.asString(["// startup", Template.asString(buf2)])
937+
} else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) {
938+
buf.push("// the startup function");
939+
buf.push(
940+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
941+
);
942+
beforeStartup.push("// run runtime startup");
943+
beforeStartup.push(`${RuntimeGlobals.startup}();`);
944+
startup.push("// startup");
945+
startup.push(Template.asString(buf2));
946+
} else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)) {
947+
buf.push("// the startup function");
948+
buf.push(
949+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
909950
);
951+
startup.push("// startup");
952+
startup.push(Template.asString(buf2));
953+
afterStartup.push("// run runtime startup");
954+
afterStartup.push(`return ${RuntimeGlobals.startup}();`);
955+
} else {
956+
startup.push("// startup");
957+
startup.push(Template.asString(buf2));
910958
}
911-
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
959+
} else if (
960+
runtimeRequirements.has(RuntimeGlobals.startup) ||
961+
runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
962+
runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
963+
) {
912964
buf.push(
913-
Template.asString([
914-
"// the startup function",
915-
"// It's empty as no entry modules are in this chunk",
916-
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
917-
"",
918-
""
919-
)}`
920-
])
965+
"// the startup function",
966+
"// It's empty as no entry modules are in this chunk",
967+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()}`,
968+
""
921969
);
922-
buf.push("");
923970
}
924-
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
971+
} else if (
972+
runtimeRequirements.has(RuntimeGlobals.startup) ||
973+
runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
974+
runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
975+
) {
925976
result.allowInlineStartup = false;
977+
buf.push(
978+
"// the startup function",
979+
"// It's empty as some runtime module handles the default behavior",
980+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()}`
981+
);
926982
startup.push("// run startup");
927983
startup.push(`return ${RuntimeGlobals.startup}();`);
928984
}

lib/node/ReadFileChunkLoadingRuntimeModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const { getUndoPath } = require("../util/identifier");
1616

1717
class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
1818
constructor(runtimeRequirements) {
19-
super("readFile chunk loading", 10);
19+
super("readFile chunk loading", RuntimeModule.STAGE_ATTACH);
2020
this.runtimeRequirements = runtimeRequirements;
2121
}
2222

lib/node/RequireChunkLoadingRuntimeModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const { getUndoPath } = require("../util/identifier");
1616

1717
class RequireChunkLoadingRuntimeModule extends RuntimeModule {
1818
constructor(runtimeRequirements) {
19-
super("require chunk loading", 10);
19+
super("require chunk loading", RuntimeModule.STAGE_ATTACH);
2020
this.runtimeRequirements = runtimeRequirements;
2121
}
2222

lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule {
1616
* @param {string} runtimeHandlers TODO
1717
*/
1818
constructor(childType, runtimeFunction, runtimeHandlers) {
19-
super(`chunk ${childType} function`, 5);
19+
super(`chunk ${childType} function`);
2020
this.childType = childType;
2121
this.runtimeFunction = runtimeFunction;
2222
this.runtimeHandlers = runtimeHandlers;

0 commit comments

Comments
 (0)