source: frontend/node_modules/webpack/lib/APIPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const {
9 getExternalModuleNodeCommonjsInitFragment
10} = require("./ExternalModule");
11const {
12 JAVASCRIPT_MODULE_TYPE_AUTO,
13 JAVASCRIPT_MODULE_TYPE_DYNAMIC,
14 JAVASCRIPT_MODULE_TYPE_ESM
15} = require("./ModuleTypeConstants");
16const RuntimeGlobals = require("./RuntimeGlobals");
17const ConstDependency = require("./dependencies/ConstDependency");
18const ModuleInitFragmentDependency = require("./dependencies/ModuleInitFragmentDependency");
19const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
20const WebpackError = require("./errors/WebpackError");
21const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");
22const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
23const {
24 evaluateToString,
25 toConstantDependency
26} = require("./javascript/JavascriptParserHelpers");
27const ChunkNameRuntimeModule = require("./runtime/ChunkNameRuntimeModule");
28const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
29
30/** @typedef {import("./Compiler")} Compiler */
31/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
32/** @typedef {import("./Module").BuildInfo} BuildInfo */
33/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
34/** @typedef {import("./javascript/JavascriptParser").Range} Range */
35
36/**
37 * Returns the replacement definitions used for webpack API identifiers.
38 * @returns {Record<string, { expr: string, req: string[] | null, type?: string, assign: boolean }>} replacements
39 */
40function getReplacements() {
41 return {
42 __webpack_require__: {
43 expr: RuntimeGlobals.require,
44 req: [RuntimeGlobals.require],
45 type: "function",
46 assign: false
47 },
48 __webpack_global__: {
49 expr: RuntimeGlobals.require,
50 req: [RuntimeGlobals.require],
51 type: "function",
52 assign: false
53 },
54 __webpack_public_path__: {
55 expr: RuntimeGlobals.publicPath,
56 req: [RuntimeGlobals.publicPath],
57 type: "string",
58 assign: true
59 },
60 __webpack_base_uri__: {
61 expr: RuntimeGlobals.baseURI,
62 req: [RuntimeGlobals.baseURI],
63 type: "string",
64 assign: true
65 },
66 __webpack_modules__: {
67 expr: RuntimeGlobals.moduleFactories,
68 req: [RuntimeGlobals.moduleFactories],
69 type: "object",
70 assign: false
71 },
72 __webpack_chunk_load__: {
73 expr: RuntimeGlobals.ensureChunk,
74 req: [RuntimeGlobals.ensureChunk],
75 type: "function",
76 assign: true
77 },
78 __non_webpack_require__: {
79 expr: "require",
80 req: null,
81 type: undefined, // type is not known, depends on environment
82 assign: true
83 },
84 __webpack_nonce__: {
85 expr: RuntimeGlobals.scriptNonce,
86 req: [RuntimeGlobals.scriptNonce],
87 type: "string",
88 assign: true
89 },
90 __webpack_hash__: {
91 expr: `${RuntimeGlobals.getFullHash}()`,
92 req: [RuntimeGlobals.getFullHash],
93 type: "string",
94 assign: false
95 },
96 __webpack_chunkname__: {
97 expr: RuntimeGlobals.chunkName,
98 req: [RuntimeGlobals.chunkName],
99 type: "string",
100 assign: false
101 },
102 __webpack_get_script_filename__: {
103 expr: RuntimeGlobals.getChunkScriptFilename,
104 req: [RuntimeGlobals.getChunkScriptFilename],
105 type: "function",
106 assign: true
107 },
108 __webpack_runtime_id__: {
109 expr: RuntimeGlobals.runtimeId,
110 req: [RuntimeGlobals.runtimeId],
111 assign: false
112 },
113 "require.onError": {
114 expr: RuntimeGlobals.uncaughtErrorHandler,
115 req: [RuntimeGlobals.uncaughtErrorHandler],
116 type: undefined, // type is not known, could be function or undefined
117 assign: true // is never a pattern
118 },
119 __system_context__: {
120 expr: RuntimeGlobals.systemContext,
121 req: [RuntimeGlobals.systemContext],
122 type: "object",
123 assign: false
124 },
125 __webpack_share_scopes__: {
126 expr: RuntimeGlobals.shareScopeMap,
127 req: [RuntimeGlobals.shareScopeMap],
128 type: "object",
129 assign: false
130 },
131 __webpack_init_sharing__: {
132 expr: RuntimeGlobals.initializeSharing,
133 req: [RuntimeGlobals.initializeSharing],
134 type: "function",
135 assign: true
136 }
137 };
138}
139
140const PLUGIN_NAME = "APIPlugin";
141
142class APIPlugin {
143 /**
144 * Applies the plugin by registering its hooks on the compiler.
145 * @param {Compiler} compiler the compiler instance
146 * @returns {void}
147 */
148 apply(compiler) {
149 compiler.hooks.compilation.tap(
150 PLUGIN_NAME,
151 (compilation, { normalModuleFactory }) => {
152 const moduleOutput = compilation.options.output.module;
153 const nodeTarget = compiler.platform.node;
154 const nodeEsm = moduleOutput && nodeTarget;
155
156 const REPLACEMENTS = getReplacements();
157 if (nodeEsm) {
158 REPLACEMENTS.__non_webpack_require__.expr =
159 "__WEBPACK_EXTERNAL_createRequire_require";
160 }
161
162 compilation.dependencyTemplates.set(
163 ConstDependency,
164 new ConstDependency.Template()
165 );
166 compilation.dependencyTemplates.set(
167 ModuleInitFragmentDependency,
168 new ModuleInitFragmentDependency.Template()
169 );
170
171 compilation.hooks.runtimeRequirementInTree
172 .for(RuntimeGlobals.chunkName)
173 .tap(PLUGIN_NAME, (chunk) => {
174 compilation.addRuntimeModule(
175 chunk,
176 new ChunkNameRuntimeModule(/** @type {string} */ (chunk.name))
177 );
178 return true;
179 });
180
181 compilation.hooks.runtimeRequirementInTree
182 .for(RuntimeGlobals.getFullHash)
183 .tap(PLUGIN_NAME, (chunk, _set) => {
184 compilation.addRuntimeModule(chunk, new GetFullHashRuntimeModule());
185 return true;
186 });
187
188 const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
189
190 hooks.renderModuleContent.tap(
191 PLUGIN_NAME,
192 (source, module, renderContext) => {
193 if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
194 const chunkInitFragments = [
195 getExternalModuleNodeCommonjsInitFragment(
196 renderContext.runtimeTemplate
197 )
198 ];
199
200 renderContext.chunkInitFragments.push(...chunkInitFragments);
201 }
202
203 return source;
204 }
205 );
206
207 /**
208 * Handles the hook callback for this code path.
209 * @param {JavascriptParser} parser the parser
210 */
211 const handler = (parser) => {
212 parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
213 if (
214 parser.scope.topLevelScope === true &&
215 declarator.id.type === "Identifier" &&
216 declarator.id.name === "module"
217 ) {
218 /** @type {BuildInfo} */
219 (parser.state.module.buildInfo).moduleArgument =
220 "__webpack_module__";
221 }
222 });
223
224 parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
225 if (parser.scope.topLevelScope === true) {
226 if (
227 statement.type === "FunctionDeclaration" &&
228 statement.id &&
229 statement.id.name === "module"
230 ) {
231 /** @type {BuildInfo} */
232 (parser.state.module.buildInfo).moduleArgument =
233 "__webpack_module__";
234 } else if (
235 statement.type === "ClassDeclaration" &&
236 statement.id &&
237 statement.id.name === "module"
238 ) {
239 /** @type {BuildInfo} */
240 (parser.state.module.buildInfo).moduleArgument =
241 "__webpack_module__";
242 }
243 }
244 });
245
246 for (const key of Object.keys(REPLACEMENTS)) {
247 const info = REPLACEMENTS[key];
248 parser.hooks.expression.for(key).tap(PLUGIN_NAME, (expression) => {
249 const dep = toConstantDependency(parser, info.expr, info.req);
250
251 if (key === "__non_webpack_require__" && moduleOutput) {
252 if (nodeTarget) {
253 /** @type {BuildInfo} */
254 (parser.state.module.buildInfo).needCreateRequire = true;
255 } else {
256 const warning = new WebpackError(
257 `${PLUGIN_NAME}\n__non_webpack_require__ is only allowed in target node`
258 );
259 warning.loc = /** @type {DependencyLocation} */ (
260 expression.loc
261 );
262 warning.module = parser.state.module;
263 compilation.warnings.push(warning);
264 }
265 }
266
267 return dep(expression);
268 });
269 if (info.assign === false) {
270 parser.hooks.assign.for(key).tap(PLUGIN_NAME, (expr) => {
271 const err = new WebpackError(`${key} must not be assigned`);
272 err.loc = /** @type {DependencyLocation} */ (expr.loc);
273 throw err;
274 });
275 }
276 if (info.type) {
277 parser.hooks.evaluateTypeof
278 .for(key)
279 .tap(PLUGIN_NAME, evaluateToString(info.type));
280 }
281 }
282
283 parser.hooks.expression
284 .for("__webpack_layer__")
285 .tap(PLUGIN_NAME, (expr) => {
286 const dep = new ConstDependency(
287 JSON.stringify(parser.state.module.layer),
288 /** @type {Range} */ (expr.range)
289 );
290 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
291 parser.state.module.addPresentationalDependency(dep);
292 return true;
293 });
294 parser.hooks.evaluateIdentifier
295 .for("__webpack_layer__")
296 .tap(PLUGIN_NAME, (expr) =>
297 (parser.state.module.layer === null
298 ? new BasicEvaluatedExpression().setNull()
299 : new BasicEvaluatedExpression().setString(
300 parser.state.module.layer
301 )
302 ).setRange(/** @type {Range} */ (expr.range))
303 );
304 parser.hooks.evaluateTypeof
305 .for("__webpack_layer__")
306 .tap(PLUGIN_NAME, (expr) =>
307 new BasicEvaluatedExpression()
308 .setString(
309 parser.state.module.layer === null ? "object" : "string"
310 )
311 .setRange(/** @type {Range} */ (expr.range))
312 );
313
314 parser.hooks.expression
315 .for("__webpack_module__.id")
316 .tap(PLUGIN_NAME, (expr) => {
317 /** @type {BuildInfo} */
318 (parser.state.module.buildInfo).moduleConcatenationBailout =
319 "__webpack_module__.id";
320 const moduleArgument = parser.state.module.moduleArgument;
321 if (moduleArgument === "__webpack_module__") {
322 const dep = new RuntimeRequirementsDependency([
323 RuntimeGlobals.moduleId
324 ]);
325 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
326 parser.state.module.addPresentationalDependency(dep);
327 } else {
328 const initDep = new ModuleInitFragmentDependency(
329 `var __webpack_internal_module_id__ = ${moduleArgument}.id;\n`,
330 [RuntimeGlobals.moduleId],
331 "__webpack_internal_module_id__"
332 );
333 parser.state.module.addPresentationalDependency(initDep);
334 const dep = new ConstDependency(
335 "__webpack_internal_module_id__",
336 /** @type {Range} */ (expr.range),
337 []
338 );
339 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
340 parser.state.module.addPresentationalDependency(dep);
341 }
342 return true;
343 });
344
345 parser.hooks.expression
346 .for("__webpack_module__")
347 .tap(PLUGIN_NAME, (expr) => {
348 /** @type {BuildInfo} */
349 (parser.state.module.buildInfo).moduleConcatenationBailout =
350 "__webpack_module__";
351 const moduleArgument = parser.state.module.moduleArgument;
352 if (moduleArgument === "__webpack_module__") {
353 const dep = new RuntimeRequirementsDependency([
354 RuntimeGlobals.module
355 ]);
356 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
357 parser.state.module.addPresentationalDependency(dep);
358 } else {
359 const initDep = new ModuleInitFragmentDependency(
360 `var __webpack_internal_module__ = ${moduleArgument};\n`,
361 [RuntimeGlobals.module],
362 "__webpack_internal_module__"
363 );
364 parser.state.module.addPresentationalDependency(initDep);
365 const dep = new ConstDependency(
366 "__webpack_internal_module__",
367 /** @type {Range} */ (expr.range),
368 []
369 );
370 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
371 parser.state.module.addPresentationalDependency(dep);
372 }
373 return true;
374 });
375 parser.hooks.evaluateTypeof
376 .for("__webpack_module__")
377 .tap(PLUGIN_NAME, evaluateToString("object"));
378 };
379
380 normalModuleFactory.hooks.parser
381 .for(JAVASCRIPT_MODULE_TYPE_AUTO)
382 .tap(PLUGIN_NAME, handler);
383 normalModuleFactory.hooks.parser
384 .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
385 .tap(PLUGIN_NAME, handler);
386 normalModuleFactory.hooks.parser
387 .for(JAVASCRIPT_MODULE_TYPE_ESM)
388 .tap(PLUGIN_NAME, handler);
389 }
390 );
391 }
392}
393
394module.exports = APIPlugin;
Note: See TracBrowser for help on using the repository browser.