UNPKG

4.01 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const RuntimeGlobals = require("../RuntimeGlobals");
9const Template = require("../Template");
10const { isSubset } = require("../util/SetHelpers");
11const { getAllChunks } = require("./ChunkHelpers");
12
13/** @typedef {import("../util/Hash")} Hash */
14/** @typedef {import("../Chunk")} Chunk */
15/** @typedef {import("../Compilation")} Compilation */
16/** @typedef {import("../ChunkGraph")} ChunkGraph */
17/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
18/** @typedef {import("../ChunkGroup")} ChunkGroup */
19/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
20/** @typedef {(string|number)[]} EntryItem */
21
22const EXPORT_PREFIX = "var __webpack_exports__ = ";
23
24/**
25 * @param {ChunkGraph} chunkGraph chunkGraph
26 * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
27 * @param {EntryModuleWithChunkGroup[]} entries entries
28 * @param {Chunk} chunk chunk
29 * @param {boolean} passive true: passive startup with on chunks loaded
30 * @returns {string} runtime code
31 */
32exports.generateEntryStartup = (
33 chunkGraph,
34 runtimeTemplate,
35 entries,
36 chunk,
37 passive
38) => {
39 /** @type {string[]} */
40 const runtime = [
41 `var __webpack_exec__ = ${runtimeTemplate.returningFunction(
42 `__webpack_require__(${RuntimeGlobals.entryModuleId} = moduleId)`,
43 "moduleId"
44 )}`
45 ];
46
47 const runModule = id => {
48 return `__webpack_exec__(${JSON.stringify(id)})`;
49 };
50 const outputCombination = (chunks, moduleIds, final) => {
51 if (chunks.size === 0) {
52 runtime.push(
53 `${final ? EXPORT_PREFIX : ""}(${moduleIds.map(runModule).join(", ")});`
54 );
55 } else {
56 const fn = runtimeTemplate.returningFunction(
57 moduleIds.map(runModule).join(", ")
58 );
59 runtime.push(
60 `${final && !passive ? EXPORT_PREFIX : ""}${
61 passive
62 ? RuntimeGlobals.onChunksLoaded
63 : RuntimeGlobals.startupEntrypoint
64 }(0, ${JSON.stringify(Array.from(chunks, c => c.id))}, ${fn});`
65 );
66 if (final && passive) {
67 runtime.push(`${EXPORT_PREFIX}${RuntimeGlobals.onChunksLoaded}();`);
68 }
69 }
70 };
71
72 let currentChunks = undefined;
73 let currentModuleIds = undefined;
74
75 for (const [module, entrypoint] of entries) {
76 const runtimeChunk = entrypoint.getRuntimeChunk();
77 const moduleId = chunkGraph.getModuleId(module);
78 const chunks = getAllChunks(entrypoint, chunk, runtimeChunk);
79 if (
80 currentChunks &&
81 currentChunks.size === chunks.size &&
82 isSubset(currentChunks, chunks)
83 ) {
84 currentModuleIds.push(moduleId);
85 } else {
86 if (currentChunks) {
87 outputCombination(currentChunks, currentModuleIds);
88 }
89 currentChunks = chunks;
90 currentModuleIds = [moduleId];
91 }
92 }
93
94 // output current modules with export prefix
95 if (currentChunks) {
96 outputCombination(currentChunks, currentModuleIds, true);
97 }
98 runtime.push("");
99 return Template.asString(runtime);
100};
101
102/**
103 * @param {Hash} hash the hash to update
104 * @param {ChunkGraph} chunkGraph chunkGraph
105 * @param {EntryModuleWithChunkGroup[]} entries entries
106 * @param {Chunk} chunk chunk
107 * @returns {void}
108 */
109exports.updateHashForEntryStartup = (hash, chunkGraph, entries, chunk) => {
110 for (const [module, entrypoint] of entries) {
111 const runtimeChunk = entrypoint.getRuntimeChunk();
112 const moduleId = chunkGraph.getModuleId(module);
113 hash.update(`${moduleId}`);
114 for (const c of getAllChunks(entrypoint, chunk, runtimeChunk))
115 hash.update(`${c.id}`);
116 }
117};
118
119/**
120 * @param {Chunk} chunk the chunk
121 * @param {ChunkGraph} chunkGraph the chunk graph
122 * @param {function(Chunk, ChunkGraph): boolean} filterFn filter function
123 * @returns {Set<number | string>} initially fulfilled chunk ids
124 */
125exports.getInitialChunkIds = (chunk, chunkGraph, filterFn) => {
126 const initialChunkIds = new Set(chunk.ids);
127 for (const c of chunk.getAllInitialChunks()) {
128 if (c === chunk || filterFn(c, chunkGraph)) continue;
129 for (const id of c.ids) initialChunkIds.add(id);
130 }
131 return initialChunkIds;
132};