UNPKG

15.7 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 { getChunkFilenameTemplate } = require("./css/CssModulesPlugin");
10const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
11const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
12const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
13const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
14const BaseUriRuntimeModule = require("./runtime/BaseUriRuntimeModule");
15const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
16const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
17const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
18const CreateScriptRuntimeModule = require("./runtime/CreateScriptRuntimeModule");
19const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule");
20const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
21const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
22const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
23const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
24const GetTrustedTypesPolicyRuntimeModule = require("./runtime/GetTrustedTypesPolicyRuntimeModule");
25const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
26const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
27const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
28const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
29const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule");
30const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
31const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
32const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
33const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
34const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
35const StringXor = require("./util/StringXor");
36
37/** @typedef {import("./Chunk")} Chunk */
38/** @typedef {import("./Compiler")} Compiler */
39/** @typedef {import("./Module")} Module */
40
41const GLOBALS_ON_REQUIRE = [
42 RuntimeGlobals.chunkName,
43 RuntimeGlobals.runtimeId,
44 RuntimeGlobals.compatGetDefaultExport,
45 RuntimeGlobals.createFakeNamespaceObject,
46 RuntimeGlobals.createScript,
47 RuntimeGlobals.createScriptUrl,
48 RuntimeGlobals.getTrustedTypesPolicy,
49 RuntimeGlobals.definePropertyGetters,
50 RuntimeGlobals.ensureChunk,
51 RuntimeGlobals.entryModuleId,
52 RuntimeGlobals.getFullHash,
53 RuntimeGlobals.global,
54 RuntimeGlobals.makeNamespaceObject,
55 RuntimeGlobals.moduleCache,
56 RuntimeGlobals.moduleFactories,
57 RuntimeGlobals.moduleFactoriesAddOnly,
58 RuntimeGlobals.interceptModuleExecution,
59 RuntimeGlobals.publicPath,
60 RuntimeGlobals.baseURI,
61 RuntimeGlobals.relativeUrl,
62 RuntimeGlobals.scriptNonce,
63 RuntimeGlobals.uncaughtErrorHandler,
64 RuntimeGlobals.asyncModule,
65 RuntimeGlobals.wasmInstances,
66 RuntimeGlobals.instantiateWasm,
67 RuntimeGlobals.shareScopeMap,
68 RuntimeGlobals.initializeSharing,
69 RuntimeGlobals.loadScript,
70 RuntimeGlobals.systemContext,
71 RuntimeGlobals.onChunksLoaded
72];
73
74const MODULE_DEPENDENCIES = {
75 [RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
76 [RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
77};
78
79const TREE_DEPENDENCIES = {
80 [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
81 [RuntimeGlobals.compatGetDefaultExport]: [
82 RuntimeGlobals.definePropertyGetters
83 ],
84 [RuntimeGlobals.createFakeNamespaceObject]: [
85 RuntimeGlobals.definePropertyGetters,
86 RuntimeGlobals.makeNamespaceObject,
87 RuntimeGlobals.require
88 ],
89 [RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
90 [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
91};
92
93class RuntimePlugin {
94 /**
95 * @param {Compiler} compiler the Compiler
96 * @returns {void}
97 */
98 apply(compiler) {
99 compiler.hooks.compilation.tap("RuntimePlugin", compilation => {
100 const globalChunkLoading = compilation.outputOptions.chunkLoading;
101 const isChunkLoadingDisabledForChunk = chunk => {
102 const options = chunk.getEntryOptions();
103 const chunkLoading =
104 options && options.chunkLoading !== undefined
105 ? options.chunkLoading
106 : globalChunkLoading;
107 return chunkLoading === false;
108 };
109 compilation.dependencyTemplates.set(
110 RuntimeRequirementsDependency,
111 new RuntimeRequirementsDependency.Template()
112 );
113 for (const req of GLOBALS_ON_REQUIRE) {
114 compilation.hooks.runtimeRequirementInModule
115 .for(req)
116 .tap("RuntimePlugin", (module, set) => {
117 set.add(RuntimeGlobals.requireScope);
118 });
119 compilation.hooks.runtimeRequirementInTree
120 .for(req)
121 .tap("RuntimePlugin", (module, set) => {
122 set.add(RuntimeGlobals.requireScope);
123 });
124 }
125 for (const req of Object.keys(TREE_DEPENDENCIES)) {
126 const deps = TREE_DEPENDENCIES[req];
127 compilation.hooks.runtimeRequirementInTree
128 .for(req)
129 .tap("RuntimePlugin", (chunk, set) => {
130 for (const dep of deps) set.add(dep);
131 });
132 }
133 for (const req of Object.keys(MODULE_DEPENDENCIES)) {
134 const deps = MODULE_DEPENDENCIES[req];
135 compilation.hooks.runtimeRequirementInModule
136 .for(req)
137 .tap("RuntimePlugin", (chunk, set) => {
138 for (const dep of deps) set.add(dep);
139 });
140 }
141 compilation.hooks.runtimeRequirementInTree
142 .for(RuntimeGlobals.definePropertyGetters)
143 .tap("RuntimePlugin", chunk => {
144 compilation.addRuntimeModule(
145 chunk,
146 new DefinePropertyGettersRuntimeModule()
147 );
148 return true;
149 });
150 compilation.hooks.runtimeRequirementInTree
151 .for(RuntimeGlobals.makeNamespaceObject)
152 .tap("RuntimePlugin", chunk => {
153 compilation.addRuntimeModule(
154 chunk,
155 new MakeNamespaceObjectRuntimeModule()
156 );
157 return true;
158 });
159 compilation.hooks.runtimeRequirementInTree
160 .for(RuntimeGlobals.createFakeNamespaceObject)
161 .tap("RuntimePlugin", chunk => {
162 compilation.addRuntimeModule(
163 chunk,
164 new CreateFakeNamespaceObjectRuntimeModule()
165 );
166 return true;
167 });
168 compilation.hooks.runtimeRequirementInTree
169 .for(RuntimeGlobals.hasOwnProperty)
170 .tap("RuntimePlugin", chunk => {
171 compilation.addRuntimeModule(
172 chunk,
173 new HasOwnPropertyRuntimeModule()
174 );
175 return true;
176 });
177 compilation.hooks.runtimeRequirementInTree
178 .for(RuntimeGlobals.compatGetDefaultExport)
179 .tap("RuntimePlugin", chunk => {
180 compilation.addRuntimeModule(
181 chunk,
182 new CompatGetDefaultExportRuntimeModule()
183 );
184 return true;
185 });
186 compilation.hooks.runtimeRequirementInTree
187 .for(RuntimeGlobals.runtimeId)
188 .tap("RuntimePlugin", chunk => {
189 compilation.addRuntimeModule(chunk, new RuntimeIdRuntimeModule());
190 return true;
191 });
192 compilation.hooks.runtimeRequirementInTree
193 .for(RuntimeGlobals.publicPath)
194 .tap("RuntimePlugin", (chunk, set) => {
195 const { outputOptions } = compilation;
196 const { publicPath: globalPublicPath, scriptType } = outputOptions;
197 const entryOptions = chunk.getEntryOptions();
198 const publicPath =
199 entryOptions && entryOptions.publicPath !== undefined
200 ? entryOptions.publicPath
201 : globalPublicPath;
202
203 if (publicPath === "auto") {
204 const module = new AutoPublicPathRuntimeModule();
205 if (scriptType !== "module") set.add(RuntimeGlobals.global);
206 compilation.addRuntimeModule(chunk, module);
207 } else {
208 const module = new PublicPathRuntimeModule(publicPath);
209
210 if (
211 typeof publicPath !== "string" ||
212 /\[(full)?hash\]/.test(publicPath)
213 ) {
214 module.fullHash = true;
215 }
216
217 compilation.addRuntimeModule(chunk, module);
218 }
219 return true;
220 });
221 compilation.hooks.runtimeRequirementInTree
222 .for(RuntimeGlobals.global)
223 .tap("RuntimePlugin", chunk => {
224 compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
225 return true;
226 });
227 compilation.hooks.runtimeRequirementInTree
228 .for(RuntimeGlobals.asyncModule)
229 .tap("RuntimePlugin", chunk => {
230 compilation.addRuntimeModule(chunk, new AsyncModuleRuntimeModule());
231 return true;
232 });
233 compilation.hooks.runtimeRequirementInTree
234 .for(RuntimeGlobals.systemContext)
235 .tap("RuntimePlugin", chunk => {
236 const { outputOptions } = compilation;
237 const { library: globalLibrary } = outputOptions;
238 const entryOptions = chunk.getEntryOptions();
239 const libraryType =
240 entryOptions && entryOptions.library !== undefined
241 ? entryOptions.library.type
242 : globalLibrary.type;
243
244 if (libraryType === "system") {
245 compilation.addRuntimeModule(
246 chunk,
247 new SystemContextRuntimeModule()
248 );
249 }
250 return true;
251 });
252 compilation.hooks.runtimeRequirementInTree
253 .for(RuntimeGlobals.getChunkScriptFilename)
254 .tap("RuntimePlugin", (chunk, set) => {
255 if (
256 typeof compilation.outputOptions.chunkFilename === "string" &&
257 /\[(full)?hash(:\d+)?\]/.test(
258 compilation.outputOptions.chunkFilename
259 )
260 ) {
261 set.add(RuntimeGlobals.getFullHash);
262 }
263 compilation.addRuntimeModule(
264 chunk,
265 new GetChunkFilenameRuntimeModule(
266 "javascript",
267 "javascript",
268 RuntimeGlobals.getChunkScriptFilename,
269 chunk =>
270 chunk.filenameTemplate ||
271 (chunk.canBeInitial()
272 ? compilation.outputOptions.filename
273 : compilation.outputOptions.chunkFilename),
274 false
275 )
276 );
277 return true;
278 });
279 compilation.hooks.runtimeRequirementInTree
280 .for(RuntimeGlobals.getChunkCssFilename)
281 .tap("RuntimePlugin", (chunk, set) => {
282 if (
283 typeof compilation.outputOptions.cssChunkFilename === "string" &&
284 /\[(full)?hash(:\d+)?\]/.test(
285 compilation.outputOptions.cssChunkFilename
286 )
287 ) {
288 set.add(RuntimeGlobals.getFullHash);
289 }
290 compilation.addRuntimeModule(
291 chunk,
292 new GetChunkFilenameRuntimeModule(
293 "css",
294 "css",
295 RuntimeGlobals.getChunkCssFilename,
296 chunk =>
297 getChunkFilenameTemplate(chunk, compilation.outputOptions),
298 set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
299 )
300 );
301 return true;
302 });
303 compilation.hooks.runtimeRequirementInTree
304 .for(RuntimeGlobals.getChunkUpdateScriptFilename)
305 .tap("RuntimePlugin", (chunk, set) => {
306 if (
307 /\[(full)?hash(:\d+)?\]/.test(
308 compilation.outputOptions.hotUpdateChunkFilename
309 )
310 )
311 set.add(RuntimeGlobals.getFullHash);
312 compilation.addRuntimeModule(
313 chunk,
314 new GetChunkFilenameRuntimeModule(
315 "javascript",
316 "javascript update",
317 RuntimeGlobals.getChunkUpdateScriptFilename,
318 c => compilation.outputOptions.hotUpdateChunkFilename,
319 true
320 )
321 );
322 return true;
323 });
324 compilation.hooks.runtimeRequirementInTree
325 .for(RuntimeGlobals.getUpdateManifestFilename)
326 .tap("RuntimePlugin", (chunk, set) => {
327 if (
328 /\[(full)?hash(:\d+)?\]/.test(
329 compilation.outputOptions.hotUpdateMainFilename
330 )
331 ) {
332 set.add(RuntimeGlobals.getFullHash);
333 }
334 compilation.addRuntimeModule(
335 chunk,
336 new GetMainFilenameRuntimeModule(
337 "update manifest",
338 RuntimeGlobals.getUpdateManifestFilename,
339 compilation.outputOptions.hotUpdateMainFilename
340 )
341 );
342 return true;
343 });
344 compilation.hooks.runtimeRequirementInTree
345 .for(RuntimeGlobals.ensureChunk)
346 .tap("RuntimePlugin", (chunk, set) => {
347 const hasAsyncChunks = chunk.hasAsyncChunks();
348 if (hasAsyncChunks) {
349 set.add(RuntimeGlobals.ensureChunkHandlers);
350 }
351 compilation.addRuntimeModule(
352 chunk,
353 new EnsureChunkRuntimeModule(set)
354 );
355 return true;
356 });
357 compilation.hooks.runtimeRequirementInTree
358 .for(RuntimeGlobals.ensureChunkIncludeEntries)
359 .tap("RuntimePlugin", (chunk, set) => {
360 set.add(RuntimeGlobals.ensureChunkHandlers);
361 });
362 compilation.hooks.runtimeRequirementInTree
363 .for(RuntimeGlobals.shareScopeMap)
364 .tap("RuntimePlugin", (chunk, set) => {
365 compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
366 return true;
367 });
368 compilation.hooks.runtimeRequirementInTree
369 .for(RuntimeGlobals.loadScript)
370 .tap("RuntimePlugin", (chunk, set) => {
371 const withCreateScriptUrl = !!compilation.outputOptions.trustedTypes;
372 if (withCreateScriptUrl) {
373 set.add(RuntimeGlobals.createScriptUrl);
374 }
375 compilation.addRuntimeModule(
376 chunk,
377 new LoadScriptRuntimeModule(withCreateScriptUrl)
378 );
379 return true;
380 });
381 compilation.hooks.runtimeRequirementInTree
382 .for(RuntimeGlobals.createScript)
383 .tap("RuntimePlugin", (chunk, set) => {
384 if (compilation.outputOptions.trustedTypes) {
385 set.add(RuntimeGlobals.getTrustedTypesPolicy);
386 }
387 compilation.addRuntimeModule(chunk, new CreateScriptRuntimeModule());
388 return true;
389 });
390 compilation.hooks.runtimeRequirementInTree
391 .for(RuntimeGlobals.createScriptUrl)
392 .tap("RuntimePlugin", (chunk, set) => {
393 if (compilation.outputOptions.trustedTypes) {
394 set.add(RuntimeGlobals.getTrustedTypesPolicy);
395 }
396 compilation.addRuntimeModule(
397 chunk,
398 new CreateScriptUrlRuntimeModule()
399 );
400 return true;
401 });
402 compilation.hooks.runtimeRequirementInTree
403 .for(RuntimeGlobals.getTrustedTypesPolicy)
404 .tap("RuntimePlugin", (chunk, set) => {
405 compilation.addRuntimeModule(
406 chunk,
407 new GetTrustedTypesPolicyRuntimeModule(set)
408 );
409 return true;
410 });
411 compilation.hooks.runtimeRequirementInTree
412 .for(RuntimeGlobals.relativeUrl)
413 .tap("RuntimePlugin", (chunk, set) => {
414 compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
415 return true;
416 });
417 compilation.hooks.runtimeRequirementInTree
418 .for(RuntimeGlobals.onChunksLoaded)
419 .tap("RuntimePlugin", (chunk, set) => {
420 compilation.addRuntimeModule(
421 chunk,
422 new OnChunksLoadedRuntimeModule()
423 );
424 return true;
425 });
426 compilation.hooks.runtimeRequirementInTree
427 .for(RuntimeGlobals.baseURI)
428 .tap("RuntimePlugin", chunk => {
429 if (isChunkLoadingDisabledForChunk(chunk)) {
430 compilation.addRuntimeModule(chunk, new BaseUriRuntimeModule());
431 return true;
432 }
433 });
434 // TODO webpack 6: remove CompatRuntimeModule
435 compilation.hooks.additionalTreeRuntimeRequirements.tap(
436 "RuntimePlugin",
437 (chunk, set) => {
438 const { mainTemplate } = compilation;
439 if (
440 mainTemplate.hooks.bootstrap.isUsed() ||
441 mainTemplate.hooks.localVars.isUsed() ||
442 mainTemplate.hooks.requireEnsure.isUsed() ||
443 mainTemplate.hooks.requireExtensions.isUsed()
444 ) {
445 compilation.addRuntimeModule(chunk, new CompatRuntimeModule());
446 }
447 }
448 );
449 JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
450 "RuntimePlugin",
451 (chunk, hash, { chunkGraph }) => {
452 const xor = new StringXor();
453 for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
454 xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
455 }
456 xor.updateHash(hash);
457 }
458 );
459 });
460 }
461}
462module.exports = RuntimePlugin;