UNPKG

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