1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const RuntimeGlobals = require("./RuntimeGlobals");
|
9 | const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
|
10 | const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
11 | const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
|
12 | const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
|
13 | const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
|
14 | const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
|
15 | const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
|
16 | const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
|
17 | const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
|
18 | const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
|
19 | const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
|
20 | const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
|
21 | const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
|
22 | const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
|
23 | const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
|
24 | const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule");
|
25 | const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
|
26 | const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
|
27 | const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
|
28 | const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
|
29 | const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
|
30 | const StringXor = require("./util/StringXor");
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | const GLOBALS_ON_REQUIRE = [
|
37 | RuntimeGlobals.chunkName,
|
38 | RuntimeGlobals.runtimeId,
|
39 | RuntimeGlobals.compatGetDefaultExport,
|
40 | RuntimeGlobals.createFakeNamespaceObject,
|
41 | RuntimeGlobals.definePropertyGetters,
|
42 | RuntimeGlobals.ensureChunk,
|
43 | RuntimeGlobals.entryModuleId,
|
44 | RuntimeGlobals.getFullHash,
|
45 | RuntimeGlobals.global,
|
46 | RuntimeGlobals.makeNamespaceObject,
|
47 | RuntimeGlobals.moduleCache,
|
48 | RuntimeGlobals.moduleFactories,
|
49 | RuntimeGlobals.moduleFactoriesAddOnly,
|
50 | RuntimeGlobals.interceptModuleExecution,
|
51 | RuntimeGlobals.publicPath,
|
52 | RuntimeGlobals.baseURI,
|
53 | RuntimeGlobals.relativeUrl,
|
54 | RuntimeGlobals.scriptNonce,
|
55 | RuntimeGlobals.uncaughtErrorHandler,
|
56 | RuntimeGlobals.asyncModule,
|
57 | RuntimeGlobals.wasmInstances,
|
58 | RuntimeGlobals.instantiateWasm,
|
59 | RuntimeGlobals.shareScopeMap,
|
60 | RuntimeGlobals.initializeSharing,
|
61 | RuntimeGlobals.loadScript,
|
62 | RuntimeGlobals.systemContext,
|
63 | RuntimeGlobals.onChunksLoaded
|
64 | ];
|
65 |
|
66 | const MODULE_DEPENDENCIES = {
|
67 | [RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
|
68 | [RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
|
69 | };
|
70 |
|
71 | const TREE_DEPENDENCIES = {
|
72 | [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
|
73 | [RuntimeGlobals.compatGetDefaultExport]: [
|
74 | RuntimeGlobals.definePropertyGetters
|
75 | ],
|
76 | [RuntimeGlobals.createFakeNamespaceObject]: [
|
77 | RuntimeGlobals.definePropertyGetters,
|
78 | RuntimeGlobals.makeNamespaceObject,
|
79 | RuntimeGlobals.require
|
80 | ],
|
81 | [RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
|
82 | [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
|
83 | };
|
84 |
|
85 | class RuntimePlugin {
|
86 | |
87 |
|
88 |
|
89 |
|
90 | apply(compiler) {
|
91 | compiler.hooks.compilation.tap("RuntimePlugin", compilation => {
|
92 | compilation.dependencyTemplates.set(
|
93 | RuntimeRequirementsDependency,
|
94 | new RuntimeRequirementsDependency.Template()
|
95 | );
|
96 | for (const req of GLOBALS_ON_REQUIRE) {
|
97 | compilation.hooks.runtimeRequirementInModule
|
98 | .for(req)
|
99 | .tap("RuntimePlugin", (module, set) => {
|
100 | set.add(RuntimeGlobals.requireScope);
|
101 | });
|
102 | compilation.hooks.runtimeRequirementInTree
|
103 | .for(req)
|
104 | .tap("RuntimePlugin", (module, set) => {
|
105 | set.add(RuntimeGlobals.requireScope);
|
106 | });
|
107 | }
|
108 | for (const req of Object.keys(TREE_DEPENDENCIES)) {
|
109 | const deps = TREE_DEPENDENCIES[req];
|
110 | compilation.hooks.runtimeRequirementInTree
|
111 | .for(req)
|
112 | .tap("RuntimePlugin", (chunk, set) => {
|
113 | for (const dep of deps) set.add(dep);
|
114 | });
|
115 | }
|
116 | for (const req of Object.keys(MODULE_DEPENDENCIES)) {
|
117 | const deps = MODULE_DEPENDENCIES[req];
|
118 | compilation.hooks.runtimeRequirementInModule
|
119 | .for(req)
|
120 | .tap("RuntimePlugin", (chunk, set) => {
|
121 | for (const dep of deps) set.add(dep);
|
122 | });
|
123 | }
|
124 | compilation.hooks.runtimeRequirementInTree
|
125 | .for(RuntimeGlobals.definePropertyGetters)
|
126 | .tap("RuntimePlugin", chunk => {
|
127 | compilation.addRuntimeModule(
|
128 | chunk,
|
129 | new DefinePropertyGettersRuntimeModule()
|
130 | );
|
131 | return true;
|
132 | });
|
133 | compilation.hooks.runtimeRequirementInTree
|
134 | .for(RuntimeGlobals.makeNamespaceObject)
|
135 | .tap("RuntimePlugin", chunk => {
|
136 | compilation.addRuntimeModule(
|
137 | chunk,
|
138 | new MakeNamespaceObjectRuntimeModule()
|
139 | );
|
140 | return true;
|
141 | });
|
142 | compilation.hooks.runtimeRequirementInTree
|
143 | .for(RuntimeGlobals.createFakeNamespaceObject)
|
144 | .tap("RuntimePlugin", chunk => {
|
145 | compilation.addRuntimeModule(
|
146 | chunk,
|
147 | new CreateFakeNamespaceObjectRuntimeModule()
|
148 | );
|
149 | return true;
|
150 | });
|
151 | compilation.hooks.runtimeRequirementInTree
|
152 | .for(RuntimeGlobals.hasOwnProperty)
|
153 | .tap("RuntimePlugin", chunk => {
|
154 | compilation.addRuntimeModule(
|
155 | chunk,
|
156 | new HasOwnPropertyRuntimeModule()
|
157 | );
|
158 | return true;
|
159 | });
|
160 | compilation.hooks.runtimeRequirementInTree
|
161 | .for(RuntimeGlobals.compatGetDefaultExport)
|
162 | .tap("RuntimePlugin", chunk => {
|
163 | compilation.addRuntimeModule(
|
164 | chunk,
|
165 | new CompatGetDefaultExportRuntimeModule()
|
166 | );
|
167 | return true;
|
168 | });
|
169 | compilation.hooks.runtimeRequirementInTree
|
170 | .for(RuntimeGlobals.runtimeId)
|
171 | .tap("RuntimePlugin", chunk => {
|
172 | compilation.addRuntimeModule(chunk, new RuntimeIdRuntimeModule());
|
173 | return true;
|
174 | });
|
175 | compilation.hooks.runtimeRequirementInTree
|
176 | .for(RuntimeGlobals.publicPath)
|
177 | .tap("RuntimePlugin", (chunk, set) => {
|
178 | const { outputOptions } = compilation;
|
179 | const { publicPath: globalPublicPath, scriptType } = outputOptions;
|
180 | const entryOptions = chunk.getEntryOptions();
|
181 | const publicPath =
|
182 | (entryOptions && entryOptions.publicPath) || globalPublicPath;
|
183 |
|
184 | if (publicPath === "auto") {
|
185 | const module = new AutoPublicPathRuntimeModule();
|
186 | if (scriptType !== "module") set.add(RuntimeGlobals.global);
|
187 | compilation.addRuntimeModule(chunk, module);
|
188 | } else {
|
189 | const module = new PublicPathRuntimeModule(publicPath);
|
190 |
|
191 | if (
|
192 | typeof publicPath !== "string" ||
|
193 | /\[(full)?hash\]/.test(publicPath)
|
194 | ) {
|
195 | module.fullHash = true;
|
196 | }
|
197 |
|
198 | compilation.addRuntimeModule(chunk, module);
|
199 | }
|
200 | return true;
|
201 | });
|
202 | compilation.hooks.runtimeRequirementInTree
|
203 | .for(RuntimeGlobals.global)
|
204 | .tap("RuntimePlugin", chunk => {
|
205 | compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
|
206 | return true;
|
207 | });
|
208 | compilation.hooks.runtimeRequirementInTree
|
209 | .for(RuntimeGlobals.asyncModule)
|
210 | .tap("RuntimePlugin", chunk => {
|
211 | compilation.addRuntimeModule(chunk, new AsyncModuleRuntimeModule());
|
212 | return true;
|
213 | });
|
214 | compilation.hooks.runtimeRequirementInTree
|
215 | .for(RuntimeGlobals.systemContext)
|
216 | .tap("RuntimePlugin", chunk => {
|
217 | if (compilation.outputOptions.library.type === "system") {
|
218 | compilation.addRuntimeModule(
|
219 | chunk,
|
220 | new SystemContextRuntimeModule()
|
221 | );
|
222 | }
|
223 | return true;
|
224 | });
|
225 | compilation.hooks.runtimeRequirementInTree
|
226 | .for(RuntimeGlobals.getChunkScriptFilename)
|
227 | .tap("RuntimePlugin", (chunk, set) => {
|
228 | if (
|
229 | typeof compilation.outputOptions.chunkFilename === "string" &&
|
230 | /\[(full)?hash(:\d+)?\]/.test(
|
231 | compilation.outputOptions.chunkFilename
|
232 | )
|
233 | ) {
|
234 | set.add(RuntimeGlobals.getFullHash);
|
235 | }
|
236 | compilation.addRuntimeModule(
|
237 | chunk,
|
238 | new GetChunkFilenameRuntimeModule(
|
239 | "javascript",
|
240 | "javascript",
|
241 | RuntimeGlobals.getChunkScriptFilename,
|
242 | chunk =>
|
243 | chunk.filenameTemplate ||
|
244 | (chunk.canBeInitial()
|
245 | ? compilation.outputOptions.filename
|
246 | : compilation.outputOptions.chunkFilename),
|
247 | false
|
248 | )
|
249 | );
|
250 | return true;
|
251 | });
|
252 | compilation.hooks.runtimeRequirementInTree
|
253 | .for(RuntimeGlobals.getChunkUpdateScriptFilename)
|
254 | .tap("RuntimePlugin", (chunk, set) => {
|
255 | if (
|
256 | /\[(full)?hash(:\d+)?\]/.test(
|
257 | compilation.outputOptions.hotUpdateChunkFilename
|
258 | )
|
259 | )
|
260 | set.add(RuntimeGlobals.getFullHash);
|
261 | compilation.addRuntimeModule(
|
262 | chunk,
|
263 | new GetChunkFilenameRuntimeModule(
|
264 | "javascript",
|
265 | "javascript update",
|
266 | RuntimeGlobals.getChunkUpdateScriptFilename,
|
267 | c => compilation.outputOptions.hotUpdateChunkFilename,
|
268 | true
|
269 | )
|
270 | );
|
271 | return true;
|
272 | });
|
273 | compilation.hooks.runtimeRequirementInTree
|
274 | .for(RuntimeGlobals.getUpdateManifestFilename)
|
275 | .tap("RuntimePlugin", (chunk, set) => {
|
276 | if (
|
277 | /\[(full)?hash(:\d+)?\]/.test(
|
278 | compilation.outputOptions.hotUpdateMainFilename
|
279 | )
|
280 | ) {
|
281 | set.add(RuntimeGlobals.getFullHash);
|
282 | }
|
283 | compilation.addRuntimeModule(
|
284 | chunk,
|
285 | new GetMainFilenameRuntimeModule(
|
286 | "update manifest",
|
287 | RuntimeGlobals.getUpdateManifestFilename,
|
288 | compilation.outputOptions.hotUpdateMainFilename
|
289 | )
|
290 | );
|
291 | return true;
|
292 | });
|
293 | compilation.hooks.runtimeRequirementInTree
|
294 | .for(RuntimeGlobals.ensureChunk)
|
295 | .tap("RuntimePlugin", (chunk, set) => {
|
296 | const hasAsyncChunks = chunk.hasAsyncChunks();
|
297 | if (hasAsyncChunks) {
|
298 | set.add(RuntimeGlobals.ensureChunkHandlers);
|
299 | }
|
300 | compilation.addRuntimeModule(
|
301 | chunk,
|
302 | new EnsureChunkRuntimeModule(set)
|
303 | );
|
304 | return true;
|
305 | });
|
306 | compilation.hooks.runtimeRequirementInTree
|
307 | .for(RuntimeGlobals.ensureChunkIncludeEntries)
|
308 | .tap("RuntimePlugin", (chunk, set) => {
|
309 | set.add(RuntimeGlobals.ensureChunkHandlers);
|
310 | });
|
311 | compilation.hooks.runtimeRequirementInTree
|
312 | .for(RuntimeGlobals.shareScopeMap)
|
313 | .tap("RuntimePlugin", (chunk, set) => {
|
314 | compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
|
315 | return true;
|
316 | });
|
317 | compilation.hooks.runtimeRequirementInTree
|
318 | .for(RuntimeGlobals.loadScript)
|
319 | .tap("RuntimePlugin", (chunk, set) => {
|
320 | compilation.addRuntimeModule(chunk, new LoadScriptRuntimeModule());
|
321 | return true;
|
322 | });
|
323 | compilation.hooks.runtimeRequirementInTree
|
324 | .for(RuntimeGlobals.relativeUrl)
|
325 | .tap("RuntimePlugin", (chunk, set) => {
|
326 | compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
|
327 | return true;
|
328 | });
|
329 | compilation.hooks.runtimeRequirementInTree
|
330 | .for(RuntimeGlobals.onChunksLoaded)
|
331 | .tap("RuntimePlugin", (chunk, set) => {
|
332 | compilation.addRuntimeModule(
|
333 | chunk,
|
334 | new OnChunksLoadedRuntimeModule()
|
335 | );
|
336 | return true;
|
337 | });
|
338 |
|
339 | compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
340 | "RuntimePlugin",
|
341 | (chunk, set) => {
|
342 | const { mainTemplate } = compilation;
|
343 | if (
|
344 | mainTemplate.hooks.bootstrap.isUsed() ||
|
345 | mainTemplate.hooks.localVars.isUsed() ||
|
346 | mainTemplate.hooks.requireEnsure.isUsed() ||
|
347 | mainTemplate.hooks.requireExtensions.isUsed()
|
348 | ) {
|
349 | compilation.addRuntimeModule(chunk, new CompatRuntimeModule());
|
350 | }
|
351 | }
|
352 | );
|
353 | JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
|
354 | "RuntimePlugin",
|
355 | (chunk, hash, { chunkGraph }) => {
|
356 | const xor = new StringXor();
|
357 | for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
|
358 | xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
|
359 | }
|
360 | xor.updateHash(hash);
|
361 | }
|
362 | );
|
363 | });
|
364 | }
|
365 | }
|
366 | module.exports = RuntimePlugin;
|