UNPKG

12.4 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 DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
17const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
18const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
19const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
20const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
21const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
22const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
23const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
24const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule");
25const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
26const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
27const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
28const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
29const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
30const StringXor = require("./util/StringXor");
31
32/** @typedef {import("./Chunk")} Chunk */
33/** @typedef {import("./Compiler")} Compiler */
34/** @typedef {import("./Module")} Module */
35
36const 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
66const MODULE_DEPENDENCIES = {
67 [RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
68 [RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
69};
70
71const 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
85class RuntimePlugin {
86 /**
87 * @param {Compiler} compiler the Compiler
88 * @returns {void}
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 // TODO webpack 6: remove CompatRuntimeModule
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}
366module.exports = RuntimePlugin;