UNPKG

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