UNPKG

12.2 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, scriptType } = outputOptions;
180
181 if (publicPath === "auto") {
182 const module = new AutoPublicPathRuntimeModule();
183 if (scriptType !== "module") set.add(RuntimeGlobals.global);
184 compilation.addRuntimeModule(chunk, module);
185 } else {
186 const module = new PublicPathRuntimeModule();
187
188 if (
189 typeof publicPath !== "string" ||
190 /\[(full)?hash\]/.test(publicPath)
191 ) {
192 module.fullHash = true;
193 }
194
195 compilation.addRuntimeModule(chunk, module);
196 }
197 return true;
198 });
199 compilation.hooks.runtimeRequirementInTree
200 .for(RuntimeGlobals.global)
201 .tap("RuntimePlugin", chunk => {
202 compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
203 return true;
204 });
205 compilation.hooks.runtimeRequirementInTree
206 .for(RuntimeGlobals.asyncModule)
207 .tap("RuntimePlugin", chunk => {
208 compilation.addRuntimeModule(chunk, new AsyncModuleRuntimeModule());
209 return true;
210 });
211 compilation.hooks.runtimeRequirementInTree
212 .for(RuntimeGlobals.systemContext)
213 .tap("RuntimePlugin", chunk => {
214 if (compilation.outputOptions.library.type === "system") {
215 compilation.addRuntimeModule(
216 chunk,
217 new SystemContextRuntimeModule()
218 );
219 }
220 return true;
221 });
222 compilation.hooks.runtimeRequirementInTree
223 .for(RuntimeGlobals.getChunkScriptFilename)
224 .tap("RuntimePlugin", (chunk, set) => {
225 if (
226 typeof compilation.outputOptions.chunkFilename === "string" &&
227 /\[(full)?hash(:\d+)?\]/.test(
228 compilation.outputOptions.chunkFilename
229 )
230 ) {
231 set.add(RuntimeGlobals.getFullHash);
232 }
233 compilation.addRuntimeModule(
234 chunk,
235 new GetChunkFilenameRuntimeModule(
236 "javascript",
237 "javascript",
238 RuntimeGlobals.getChunkScriptFilename,
239 chunk =>
240 chunk.filenameTemplate ||
241 (chunk.canBeInitial()
242 ? compilation.outputOptions.filename
243 : compilation.outputOptions.chunkFilename),
244 false
245 )
246 );
247 return true;
248 });
249 compilation.hooks.runtimeRequirementInTree
250 .for(RuntimeGlobals.getChunkUpdateScriptFilename)
251 .tap("RuntimePlugin", (chunk, set) => {
252 if (
253 /\[(full)?hash(:\d+)?\]/.test(
254 compilation.outputOptions.hotUpdateChunkFilename
255 )
256 )
257 set.add(RuntimeGlobals.getFullHash);
258 compilation.addRuntimeModule(
259 chunk,
260 new GetChunkFilenameRuntimeModule(
261 "javascript",
262 "javascript update",
263 RuntimeGlobals.getChunkUpdateScriptFilename,
264 c => compilation.outputOptions.hotUpdateChunkFilename,
265 true
266 )
267 );
268 return true;
269 });
270 compilation.hooks.runtimeRequirementInTree
271 .for(RuntimeGlobals.getUpdateManifestFilename)
272 .tap("RuntimePlugin", (chunk, set) => {
273 if (
274 /\[(full)?hash(:\d+)?\]/.test(
275 compilation.outputOptions.hotUpdateMainFilename
276 )
277 ) {
278 set.add(RuntimeGlobals.getFullHash);
279 }
280 compilation.addRuntimeModule(
281 chunk,
282 new GetMainFilenameRuntimeModule(
283 "update manifest",
284 RuntimeGlobals.getUpdateManifestFilename,
285 compilation.outputOptions.hotUpdateMainFilename
286 )
287 );
288 return true;
289 });
290 compilation.hooks.runtimeRequirementInTree
291 .for(RuntimeGlobals.ensureChunk)
292 .tap("RuntimePlugin", (chunk, set) => {
293 const hasAsyncChunks = chunk.hasAsyncChunks();
294 if (hasAsyncChunks) {
295 set.add(RuntimeGlobals.ensureChunkHandlers);
296 }
297 compilation.addRuntimeModule(
298 chunk,
299 new EnsureChunkRuntimeModule(set)
300 );
301 return true;
302 });
303 compilation.hooks.runtimeRequirementInTree
304 .for(RuntimeGlobals.ensureChunkIncludeEntries)
305 .tap("RuntimePlugin", (chunk, set) => {
306 set.add(RuntimeGlobals.ensureChunkHandlers);
307 });
308 compilation.hooks.runtimeRequirementInTree
309 .for(RuntimeGlobals.shareScopeMap)
310 .tap("RuntimePlugin", (chunk, set) => {
311 compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
312 return true;
313 });
314 compilation.hooks.runtimeRequirementInTree
315 .for(RuntimeGlobals.loadScript)
316 .tap("RuntimePlugin", (chunk, set) => {
317 compilation.addRuntimeModule(chunk, new LoadScriptRuntimeModule());
318 return true;
319 });
320 compilation.hooks.runtimeRequirementInTree
321 .for(RuntimeGlobals.relativeUrl)
322 .tap("RuntimePlugin", (chunk, set) => {
323 compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
324 return true;
325 });
326 compilation.hooks.runtimeRequirementInTree
327 .for(RuntimeGlobals.onChunksLoaded)
328 .tap("RuntimePlugin", (chunk, set) => {
329 compilation.addRuntimeModule(
330 chunk,
331 new OnChunksLoadedRuntimeModule()
332 );
333 return true;
334 });
335 // TODO webpack 6: remove CompatRuntimeModule
336 compilation.hooks.additionalTreeRuntimeRequirements.tap(
337 "RuntimePlugin",
338 (chunk, set) => {
339 const { mainTemplate } = compilation;
340 if (
341 mainTemplate.hooks.bootstrap.isUsed() ||
342 mainTemplate.hooks.localVars.isUsed() ||
343 mainTemplate.hooks.requireEnsure.isUsed() ||
344 mainTemplate.hooks.requireExtensions.isUsed()
345 ) {
346 compilation.addRuntimeModule(chunk, new CompatRuntimeModule());
347 }
348 }
349 );
350 JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
351 "RuntimePlugin",
352 (chunk, hash, { chunkGraph }) => {
353 const xor = new StringXor();
354 for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
355 xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
356 }
357 xor.updateHash(hash);
358 }
359 );
360 });
361 }
362}
363module.exports = RuntimePlugin;