webpack 5.105.2 → 5.105.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/CleanPlugin.js +1 -0
  2. package/lib/Compilation.js +8 -6
  3. package/lib/ContextModule.js +14 -8
  4. package/lib/Dependency.js +1 -1
  5. package/lib/EnvironmentNotSupportAsyncWarning.js +1 -0
  6. package/lib/EvalDevToolModulePlugin.js +3 -0
  7. package/lib/EvalSourceMapDevToolPlugin.js +8 -1
  8. package/lib/ExportsInfo.js +0 -30
  9. package/lib/ExternalModule.js +2 -2
  10. package/lib/Module.js +30 -5
  11. package/lib/ModuleGraphConnection.js +0 -9
  12. package/lib/SourceMapDevToolModuleOptionsPlugin.js +1 -0
  13. package/lib/SourceMapDevToolPlugin.js +10 -2
  14. package/lib/WebpackOptionsApply.js +13 -3
  15. package/lib/asset/AssetModulesPlugin.js +16 -1
  16. package/lib/asset/RawDataUrlModule.js +5 -1
  17. package/lib/css/CssGenerator.js +3 -6
  18. package/lib/css/CssModulesPlugin.js +7 -0
  19. package/lib/dependencies/CommonJsExportRequireDependency.js +4 -0
  20. package/lib/dependencies/CommonJsImportsParserPlugin.js +314 -508
  21. package/lib/dependencies/CreateRequireParserPlugin.js +345 -0
  22. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +4 -8
  23. package/lib/dependencies/HarmonyImportDependency.js +30 -0
  24. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -20
  25. package/lib/dependencies/HarmonyModulesPlugin.js +4 -0
  26. package/lib/dependencies/ImportParserPlugin.js +1 -11
  27. package/lib/dependencies/ImportPhase.js +4 -0
  28. package/lib/javascript/JavascriptModulesPlugin.js +75 -22
  29. package/lib/javascript/JavascriptParser.js +2 -2
  30. package/lib/performance/AssetsOverSizeLimitWarning.js +1 -0
  31. package/lib/performance/EntrypointsOverSizeLimitWarning.js +1 -0
  32. package/lib/performance/SizeLimitsPlugin.js +1 -0
  33. package/lib/runtime/ToBinaryRuntimeModule.js +14 -6
  34. package/lib/util/findGraphRoots.js +79 -109
  35. package/package.json +12 -9
  36. package/types.d.ts +147 -62
@@ -5,13 +5,9 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { fileURLToPath } = require("url");
9
8
  const CommentCompilationWarning = require("../CommentCompilationWarning");
10
9
  const RuntimeGlobals = require("../RuntimeGlobals");
11
10
  const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
12
- const WebpackError = require("../WebpackError");
13
- const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
14
- const { VariableInfo } = require("../javascript/JavascriptParser");
15
11
  const {
16
12
  evaluateToIdentifier,
17
13
  evaluateToString,
@@ -36,6 +32,7 @@ const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency
36
32
  /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
37
33
  /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
38
34
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
35
+ /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
39
36
  /** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
40
37
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
41
38
  /** @typedef {import("../javascript/JavascriptParser").Members} Members */
@@ -48,11 +45,300 @@ const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency
48
45
  * @property {string} context
49
46
  */
50
47
 
51
- const createRequireSpecifierTag = Symbol("createRequire");
52
- const createdRequireIdentifierTag = Symbol("createRequire()");
53
-
54
48
  const PLUGIN_NAME = "CommonJsImportsParserPlugin";
55
49
 
50
+ /**
51
+ * @param {JavascriptParser} parser parser
52
+ * @returns {(expr: Expression) => boolean} handler
53
+ */
54
+ const createRequireCacheDependency = (parser) =>
55
+ toConstantDependency(parser, RuntimeGlobals.moduleCache, [
56
+ RuntimeGlobals.moduleCache,
57
+ RuntimeGlobals.moduleId,
58
+ RuntimeGlobals.moduleLoaded
59
+ ]);
60
+
61
+ /**
62
+ * @param {JavascriptParser} parser parser
63
+ * @param {JavascriptParserOptions} options options
64
+ * @param {() => undefined | string} getContext context accessor
65
+ * @returns {(expr: Expression) => boolean} handler
66
+ */
67
+ const createRequireAsExpressionHandler =
68
+ (parser, options, getContext) => (expr) => {
69
+ const dep = new CommonJsRequireContextDependency(
70
+ {
71
+ request: /** @type {string} */ (options.unknownContextRequest),
72
+ recursive: /** @type {boolean} */ (options.unknownContextRecursive),
73
+ regExp: /** @type {RegExp} */ (options.unknownContextRegExp),
74
+ mode: "sync"
75
+ },
76
+ /** @type {Range} */ (expr.range),
77
+ undefined,
78
+ parser.scope.inShorthand,
79
+ getContext()
80
+ );
81
+ dep.critical =
82
+ options.unknownContextCritical &&
83
+ "require function is used in a way in which dependencies cannot be statically extracted";
84
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
85
+ dep.optional = Boolean(parser.scope.inTry);
86
+ parser.state.current.addDependency(dep);
87
+ return true;
88
+ };
89
+
90
+ /**
91
+ * @param {JavascriptParser} parser parser
92
+ * @param {JavascriptParserOptions} options options
93
+ * @param {() => undefined | string} getContext context accessor
94
+ * @returns {(callNew: boolean) => (expr: CallExpression | NewExpression) => (boolean | void)} handler factory
95
+ */
96
+ const createRequireCallHandler = (parser, options, getContext) => {
97
+ /**
98
+ * @param {CallExpression | NewExpression} expr expression
99
+ * @param {BasicEvaluatedExpression} param param
100
+ * @returns {boolean | void} true when handled
101
+ */
102
+ const processRequireItem = (expr, param) => {
103
+ if (param.isString()) {
104
+ const dep = new CommonJsRequireDependency(
105
+ /** @type {string} */ (param.string),
106
+ /** @type {Range} */ (param.range),
107
+ getContext()
108
+ );
109
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
110
+ dep.optional = Boolean(parser.scope.inTry);
111
+ parser.state.current.addDependency(dep);
112
+ return true;
113
+ }
114
+ };
115
+ /**
116
+ * @param {CallExpression | NewExpression} expr expression
117
+ * @param {BasicEvaluatedExpression} param param
118
+ * @returns {boolean | void} true when handled
119
+ */
120
+ const processRequireContext = (expr, param) => {
121
+ const dep = ContextDependencyHelpers.create(
122
+ CommonJsRequireContextDependency,
123
+ /** @type {Range} */ (expr.range),
124
+ param,
125
+ expr,
126
+ options,
127
+ {
128
+ category: "commonjs"
129
+ },
130
+ parser,
131
+ undefined,
132
+ getContext()
133
+ );
134
+ if (!dep) return;
135
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
136
+ dep.optional = Boolean(parser.scope.inTry);
137
+ parser.state.current.addDependency(dep);
138
+ return true;
139
+ };
140
+
141
+ return (callNew) => (expr) => {
142
+ if (options.commonjsMagicComments) {
143
+ const { options: requireOptions, errors: commentErrors } =
144
+ parser.parseCommentOptions(/** @type {Range} */ (expr.range));
145
+
146
+ if (commentErrors) {
147
+ for (const e of commentErrors) {
148
+ const { comment } = e;
149
+ parser.state.module.addWarning(
150
+ new CommentCompilationWarning(
151
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
152
+ /** @type {DependencyLocation} */ (comment.loc)
153
+ )
154
+ );
155
+ }
156
+ }
157
+ if (requireOptions && requireOptions.webpackIgnore !== undefined) {
158
+ if (typeof requireOptions.webpackIgnore !== "boolean") {
159
+ parser.state.module.addWarning(
160
+ new UnsupportedFeatureWarning(
161
+ `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
162
+ /** @type {DependencyLocation} */ (expr.loc)
163
+ )
164
+ );
165
+ } else if (requireOptions.webpackIgnore) {
166
+ // Do not instrument `require()` if `webpackIgnore` is `true`
167
+ return true;
168
+ }
169
+ }
170
+ }
171
+
172
+ if (expr.arguments.length !== 1) return;
173
+ /** @type {null | LocalModule} */
174
+ let localModule;
175
+ const param = parser.evaluateExpression(expr.arguments[0]);
176
+ if (param.isConditional()) {
177
+ let isExpression = false;
178
+ for (const p of /** @type {BasicEvaluatedExpression[]} */ (
179
+ param.options
180
+ )) {
181
+ const result = processRequireItem(expr, p);
182
+ if (result === undefined) {
183
+ isExpression = true;
184
+ }
185
+ }
186
+ if (!isExpression) {
187
+ const dep = new RequireHeaderDependency(
188
+ /** @type {Range} */ (expr.callee.range)
189
+ );
190
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
191
+ parser.state.module.addPresentationalDependency(dep);
192
+ return true;
193
+ }
194
+ }
195
+ if (
196
+ param.isString() &&
197
+ (localModule = getLocalModule(
198
+ parser.state,
199
+ /** @type {string} */ (param.string)
200
+ ))
201
+ ) {
202
+ localModule.flagUsed();
203
+ const dep = new LocalModuleDependency(
204
+ localModule,
205
+ /** @type {Range} */ (expr.range),
206
+ callNew
207
+ );
208
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
209
+ parser.state.module.addPresentationalDependency(dep);
210
+ } else {
211
+ const result = processRequireItem(expr, param);
212
+ if (result === undefined) {
213
+ processRequireContext(expr, param);
214
+ } else {
215
+ const dep = new RequireHeaderDependency(
216
+ /** @type {Range} */ (expr.callee.range)
217
+ );
218
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
219
+ parser.state.module.addPresentationalDependency(dep);
220
+ }
221
+ }
222
+ return true;
223
+ };
224
+ };
225
+
226
+ /**
227
+ * @param {JavascriptParser} parser parser
228
+ * @param {JavascriptParserOptions} options options
229
+ * @param {() => undefined | string} getContext context accessor
230
+ * @returns {(expr: CallExpression, weak: boolean) => (boolean | void)} resolver
231
+ */
232
+ const createProcessResolveHandler = (parser, options, getContext) => {
233
+ /**
234
+ * @param {CallExpression} expr call expression
235
+ * @param {BasicEvaluatedExpression} param param
236
+ * @param {boolean} weak weak
237
+ * @returns {boolean | void} true when handled
238
+ */
239
+ const processResolveItem = (expr, param, weak) => {
240
+ if (param.isString()) {
241
+ const dep = new RequireResolveDependency(
242
+ /** @type {string} */ (param.string),
243
+ /** @type {Range} */ (param.range),
244
+ getContext()
245
+ );
246
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
247
+ dep.optional = Boolean(parser.scope.inTry);
248
+ dep.weak = weak;
249
+ parser.state.current.addDependency(dep);
250
+ return true;
251
+ }
252
+ };
253
+ /**
254
+ * @param {CallExpression} expr call expression
255
+ * @param {BasicEvaluatedExpression} param param
256
+ * @param {boolean} weak weak
257
+ * @returns {boolean | void} true when handled
258
+ */
259
+ const processResolveContext = (expr, param, weak) => {
260
+ const dep = ContextDependencyHelpers.create(
261
+ RequireResolveContextDependency,
262
+ /** @type {Range} */ (param.range),
263
+ param,
264
+ expr,
265
+ options,
266
+ {
267
+ category: "commonjs",
268
+ mode: weak ? "weak" : "sync"
269
+ },
270
+ parser,
271
+ getContext()
272
+ );
273
+ if (!dep) return;
274
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
275
+ dep.optional = Boolean(parser.scope.inTry);
276
+ parser.state.current.addDependency(dep);
277
+ return true;
278
+ };
279
+
280
+ return (expr, weak) => {
281
+ if (!weak && options.commonjsMagicComments) {
282
+ const { options: requireOptions, errors: commentErrors } =
283
+ parser.parseCommentOptions(/** @type {Range} */ (expr.range));
284
+
285
+ if (commentErrors) {
286
+ for (const e of commentErrors) {
287
+ const { comment } = e;
288
+ parser.state.module.addWarning(
289
+ new CommentCompilationWarning(
290
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
291
+ /** @type {DependencyLocation} */ (comment.loc)
292
+ )
293
+ );
294
+ }
295
+ }
296
+ if (requireOptions && requireOptions.webpackIgnore !== undefined) {
297
+ if (typeof requireOptions.webpackIgnore !== "boolean") {
298
+ parser.state.module.addWarning(
299
+ new UnsupportedFeatureWarning(
300
+ `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
301
+ /** @type {DependencyLocation} */ (expr.loc)
302
+ )
303
+ );
304
+ } else if (requireOptions.webpackIgnore) {
305
+ // Do not instrument `require()` if `webpackIgnore` is `true`
306
+ return true;
307
+ }
308
+ }
309
+ }
310
+
311
+ if (expr.arguments.length !== 1) return;
312
+ const param = parser.evaluateExpression(expr.arguments[0]);
313
+ if (param.isConditional()) {
314
+ for (const option of /** @type {BasicEvaluatedExpression[]} */ (
315
+ param.options
316
+ )) {
317
+ const result = processResolveItem(expr, option, weak);
318
+ if (result === undefined) {
319
+ processResolveContext(expr, option, weak);
320
+ }
321
+ }
322
+ const dep = new RequireResolveHeaderDependency(
323
+ /** @type {Range} */ (expr.callee.range)
324
+ );
325
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
326
+ parser.state.module.addPresentationalDependency(dep);
327
+ return true;
328
+ }
329
+ const result = processResolveItem(expr, param, weak);
330
+ if (result === undefined) {
331
+ processResolveContext(expr, param, weak);
332
+ }
333
+ const dep = new RequireResolveHeaderDependency(
334
+ /** @type {Range} */ (expr.callee.range)
335
+ );
336
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
337
+ parser.state.module.addPresentationalDependency(dep);
338
+ return true;
339
+ };
340
+ };
341
+
56
342
  class CommonJsImportsParserPlugin {
57
343
  /**
58
344
  * @param {JavascriptParserOptions} options parser options
@@ -98,20 +384,6 @@ class CommonJsImportsParserPlugin {
98
384
  evaluateToIdentifier(expression, "require", getMembers, true)
99
385
  );
100
386
  };
101
- /**
102
- * @param {string | symbol} tag tag
103
- */
104
- const tapRequireExpressionTag = (tag) => {
105
- parser.hooks.typeof
106
- .for(tag)
107
- .tap(
108
- PLUGIN_NAME,
109
- toConstantDependency(parser, JSON.stringify("function"))
110
- );
111
- parser.hooks.evaluateTypeof
112
- .for(tag)
113
- .tap(PLUGIN_NAME, evaluateToString("function"));
114
- };
115
387
  tapRequireExpression("require", () => []);
116
388
  tapRequireExpression("require.resolve", () => ["resolve"]);
117
389
  tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
@@ -176,15 +448,7 @@ class CommonJsImportsParserPlugin {
176
448
  // #endregion
177
449
 
178
450
  // #region Inspection
179
- const requireCache = toConstantDependency(
180
- parser,
181
- RuntimeGlobals.moduleCache,
182
- [
183
- RuntimeGlobals.moduleCache,
184
- RuntimeGlobals.moduleId,
185
- RuntimeGlobals.moduleLoaded
186
- ]
187
- );
451
+ const requireCache = createRequireCacheDependency(parser);
188
452
 
189
453
  parser.hooks.expression.for("require.cache").tap(PLUGIN_NAME, requireCache);
190
454
  // #endregion
@@ -194,163 +458,26 @@ class CommonJsImportsParserPlugin {
194
458
  * @param {Expression} expr expression
195
459
  * @returns {boolean} true when handled
196
460
  */
197
- const requireAsExpressionHandler = (expr) => {
198
- const dep = new CommonJsRequireContextDependency(
199
- {
200
- request: /** @type {string} */ (options.unknownContextRequest),
201
- recursive: /** @type {boolean} */ (options.unknownContextRecursive),
202
- regExp: /** @type {RegExp} */ (options.unknownContextRegExp),
203
- mode: "sync"
204
- },
205
- /** @type {Range} */ (expr.range),
206
- undefined,
207
- parser.scope.inShorthand,
208
- getContext()
209
- );
210
- dep.critical =
211
- options.unknownContextCritical &&
212
- "require function is used in a way in which dependencies cannot be statically extracted";
213
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
214
- dep.optional = Boolean(parser.scope.inTry);
215
- parser.state.current.addDependency(dep);
216
- return true;
217
- };
461
+ const requireAsExpressionHandler = createRequireAsExpressionHandler(
462
+ parser,
463
+ options,
464
+ getContext
465
+ );
218
466
  parser.hooks.expression
219
467
  .for("require")
220
468
  .tap(PLUGIN_NAME, requireAsExpressionHandler);
221
469
  // #endregion
222
470
 
223
471
  // #region Require
224
- /**
225
- * @param {CallExpression | NewExpression} expr expression
226
- * @param {BasicEvaluatedExpression} param param
227
- * @returns {boolean | void} true when handled
228
- */
229
- const processRequireItem = (expr, param) => {
230
- if (param.isString()) {
231
- const dep = new CommonJsRequireDependency(
232
- /** @type {string} */ (param.string),
233
- /** @type {Range} */ (param.range),
234
- getContext()
235
- );
236
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
237
- dep.optional = Boolean(parser.scope.inTry);
238
- parser.state.current.addDependency(dep);
239
- return true;
240
- }
241
- };
242
- /**
243
- * @param {CallExpression | NewExpression} expr expression
244
- * @param {BasicEvaluatedExpression} param param
245
- * @returns {boolean | void} true when handled
246
- */
247
- const processRequireContext = (expr, param) => {
248
- const dep = ContextDependencyHelpers.create(
249
- CommonJsRequireContextDependency,
250
- /** @type {Range} */ (expr.range),
251
- param,
252
- expr,
253
- options,
254
- {
255
- category: "commonjs"
256
- },
257
- parser,
258
- undefined,
259
- getContext()
260
- );
261
- if (!dep) return;
262
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
263
- dep.optional = Boolean(parser.scope.inTry);
264
- parser.state.current.addDependency(dep);
265
- return true;
266
- };
267
472
  /**
268
473
  * @param {boolean} callNew true, when require is called with new
269
474
  * @returns {(expr: CallExpression | NewExpression) => (boolean | void)} handler
270
475
  */
271
- const createRequireHandler = (callNew) => (expr) => {
272
- if (options.commonjsMagicComments) {
273
- const { options: requireOptions, errors: commentErrors } =
274
- parser.parseCommentOptions(/** @type {Range} */ (expr.range));
275
-
276
- if (commentErrors) {
277
- for (const e of commentErrors) {
278
- const { comment } = e;
279
- parser.state.module.addWarning(
280
- new CommentCompilationWarning(
281
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
282
- /** @type {DependencyLocation} */ (comment.loc)
283
- )
284
- );
285
- }
286
- }
287
- if (requireOptions && requireOptions.webpackIgnore !== undefined) {
288
- if (typeof requireOptions.webpackIgnore !== "boolean") {
289
- parser.state.module.addWarning(
290
- new UnsupportedFeatureWarning(
291
- `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
292
- /** @type {DependencyLocation} */ (expr.loc)
293
- )
294
- );
295
- } else if (requireOptions.webpackIgnore) {
296
- // Do not instrument `require()` if `webpackIgnore` is `true`
297
- return true;
298
- }
299
- }
300
- }
301
-
302
- if (expr.arguments.length !== 1) return;
303
- /** @type {null | LocalModule} */
304
- let localModule;
305
- const param = parser.evaluateExpression(expr.arguments[0]);
306
- if (param.isConditional()) {
307
- let isExpression = false;
308
- for (const p of /** @type {BasicEvaluatedExpression[]} */ (
309
- param.options
310
- )) {
311
- const result = processRequireItem(expr, p);
312
- if (result === undefined) {
313
- isExpression = true;
314
- }
315
- }
316
- if (!isExpression) {
317
- const dep = new RequireHeaderDependency(
318
- /** @type {Range} */ (expr.callee.range)
319
- );
320
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
321
- parser.state.module.addPresentationalDependency(dep);
322
- return true;
323
- }
324
- }
325
- if (
326
- param.isString() &&
327
- (localModule = getLocalModule(
328
- parser.state,
329
- /** @type {string} */ (param.string)
330
- ))
331
- ) {
332
- localModule.flagUsed();
333
- const dep = new LocalModuleDependency(
334
- localModule,
335
- /** @type {Range} */ (expr.range),
336
- callNew
337
- );
338
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
339
- parser.state.module.addPresentationalDependency(dep);
340
- } else {
341
- const result = processRequireItem(expr, param);
342
- if (result === undefined) {
343
- processRequireContext(expr, param);
344
- } else {
345
- const dep = new RequireHeaderDependency(
346
- /** @type {Range} */ (expr.callee.range)
347
- );
348
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
349
- parser.state.module.addPresentationalDependency(dep);
350
- }
351
- }
352
- return true;
353
- };
476
+ const createRequireHandler = createRequireCallHandler(
477
+ parser,
478
+ options,
479
+ getContext
480
+ );
354
481
  parser.hooks.call
355
482
  .for("require")
356
483
  .tap(PLUGIN_NAME, createRequireHandler(false));
@@ -460,112 +587,11 @@ class CommonJsImportsParserPlugin {
460
587
  * @param {boolean} weak weak
461
588
  * @returns {boolean | void} true when handled
462
589
  */
463
- const processResolve = (expr, weak) => {
464
- if (!weak && options.commonjsMagicComments) {
465
- const { options: requireOptions, errors: commentErrors } =
466
- parser.parseCommentOptions(/** @type {Range} */ (expr.range));
467
-
468
- if (commentErrors) {
469
- for (const e of commentErrors) {
470
- const { comment } = e;
471
- parser.state.module.addWarning(
472
- new CommentCompilationWarning(
473
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
474
- /** @type {DependencyLocation} */ (comment.loc)
475
- )
476
- );
477
- }
478
- }
479
- if (requireOptions && requireOptions.webpackIgnore !== undefined) {
480
- if (typeof requireOptions.webpackIgnore !== "boolean") {
481
- parser.state.module.addWarning(
482
- new UnsupportedFeatureWarning(
483
- `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
484
- /** @type {DependencyLocation} */ (expr.loc)
485
- )
486
- );
487
- } else if (requireOptions.webpackIgnore) {
488
- // Do not instrument `require()` if `webpackIgnore` is `true`
489
- return true;
490
- }
491
- }
492
- }
493
-
494
- if (expr.arguments.length !== 1) return;
495
- const param = parser.evaluateExpression(expr.arguments[0]);
496
- if (param.isConditional()) {
497
- for (const option of /** @type {BasicEvaluatedExpression[]} */ (
498
- param.options
499
- )) {
500
- const result = processResolveItem(expr, option, weak);
501
- if (result === undefined) {
502
- processResolveContext(expr, option, weak);
503
- }
504
- }
505
- const dep = new RequireResolveHeaderDependency(
506
- /** @type {Range} */ (expr.callee.range)
507
- );
508
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
509
- parser.state.module.addPresentationalDependency(dep);
510
- return true;
511
- }
512
- const result = processResolveItem(expr, param, weak);
513
- if (result === undefined) {
514
- processResolveContext(expr, param, weak);
515
- }
516
- const dep = new RequireResolveHeaderDependency(
517
- /** @type {Range} */ (expr.callee.range)
518
- );
519
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
520
- parser.state.module.addPresentationalDependency(dep);
521
- return true;
522
- };
523
- /**
524
- * @param {CallExpression} expr call expression
525
- * @param {BasicEvaluatedExpression} param param
526
- * @param {boolean} weak weak
527
- * @returns {boolean | void} true when handled
528
- */
529
- const processResolveItem = (expr, param, weak) => {
530
- if (param.isString()) {
531
- const dep = new RequireResolveDependency(
532
- /** @type {string} */ (param.string),
533
- /** @type {Range} */ (param.range),
534
- getContext()
535
- );
536
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
537
- dep.optional = Boolean(parser.scope.inTry);
538
- dep.weak = weak;
539
- parser.state.current.addDependency(dep);
540
- return true;
541
- }
542
- };
543
- /**
544
- * @param {CallExpression} expr call expression
545
- * @param {BasicEvaluatedExpression} param param
546
- * @param {boolean} weak weak
547
- * @returns {boolean | void} true when handled
548
- */
549
- const processResolveContext = (expr, param, weak) => {
550
- const dep = ContextDependencyHelpers.create(
551
- RequireResolveContextDependency,
552
- /** @type {Range} */ (param.range),
553
- param,
554
- expr,
555
- options,
556
- {
557
- category: "commonjs",
558
- mode: weak ? "weak" : "sync"
559
- },
560
- parser,
561
- getContext()
562
- );
563
- if (!dep) return;
564
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
565
- dep.optional = Boolean(parser.scope.inTry);
566
- parser.state.current.addDependency(dep);
567
- return true;
568
- };
590
+ const processResolve = createProcessResolveHandler(
591
+ parser,
592
+ options,
593
+ getContext
594
+ );
569
595
 
570
596
  parser.hooks.call
571
597
  .for("require.resolve")
@@ -574,232 +600,12 @@ class CommonJsImportsParserPlugin {
574
600
  .for("require.resolveWeak")
575
601
  .tap(PLUGIN_NAME, (expr) => processResolve(expr, true));
576
602
  // #endregion
577
-
578
- // #region Create require
579
-
580
- if (!options.createRequire) return;
581
-
582
- /** @type {ImportSource[]} */
583
- let moduleName = [];
584
- /** @type {string | undefined} */
585
- let specifierName;
586
-
587
- if (options.createRequire === true) {
588
- moduleName = ["module", "node:module"];
589
- specifierName = "createRequire";
590
- } else {
591
- /** @type {undefined | string} */
592
- let moduleName;
593
- const match = /^(.*) from (.*)$/.exec(options.createRequire);
594
- if (match) {
595
- [, specifierName, moduleName] = match;
596
- }
597
- if (!specifierName || !moduleName) {
598
- const err = new WebpackError(
599
- `Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
600
- options.createRequire
601
- )}`
602
- );
603
- err.details =
604
- 'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
605
- throw err;
606
- }
607
- }
608
-
609
- tapRequireExpressionTag(createdRequireIdentifierTag);
610
- tapRequireExpressionTag(createRequireSpecifierTag);
611
- parser.hooks.evaluateCallExpression
612
- .for(createRequireSpecifierTag)
613
- .tap(PLUGIN_NAME, (expr) => {
614
- const context = parseCreateRequireArguments(expr);
615
- if (context === undefined) return;
616
- const ident = parser.evaluatedVariable({
617
- tag: createdRequireIdentifierTag,
618
- data: { context },
619
- next: undefined
620
- });
621
-
622
- return new BasicEvaluatedExpression()
623
- .setIdentifier(ident, ident, () => [])
624
- .setSideEffects(false)
625
- .setRange(/** @type {Range} */ (expr.range));
626
- });
627
- parser.hooks.unhandledExpressionMemberChain
628
- .for(createdRequireIdentifierTag)
629
- .tap(PLUGIN_NAME, (expr, members) =>
630
- expressionIsUnsupported(
631
- parser,
632
- `createRequire().${members.join(".")} is not supported by webpack.`
633
- )(expr)
634
- );
635
- parser.hooks.canRename
636
- .for(createdRequireIdentifierTag)
637
- .tap(PLUGIN_NAME, () => true);
638
- parser.hooks.canRename
639
- .for(createRequireSpecifierTag)
640
- .tap(PLUGIN_NAME, () => true);
641
- parser.hooks.rename
642
- .for(createRequireSpecifierTag)
643
- .tap(PLUGIN_NAME, defineUndefined);
644
- parser.hooks.expression
645
- .for(createdRequireIdentifierTag)
646
- .tap(PLUGIN_NAME, requireAsExpressionHandler);
647
- parser.hooks.call
648
- .for(createdRequireIdentifierTag)
649
- .tap(PLUGIN_NAME, createRequireHandler(false));
650
- /**
651
- * @param {CallExpression} expr call expression
652
- * @returns {string | void} context
653
- */
654
- const parseCreateRequireArguments = (expr) => {
655
- const args = expr.arguments;
656
- if (args.length !== 1) {
657
- const err = new WebpackError(
658
- "module.createRequire supports only one argument."
659
- );
660
- err.loc = /** @type {DependencyLocation} */ (expr.loc);
661
- parser.state.module.addWarning(err);
662
- return;
663
- }
664
- const arg = args[0];
665
- const evaluated = parser.evaluateExpression(arg);
666
- if (!evaluated.isString()) {
667
- const err = new WebpackError(
668
- "module.createRequire failed parsing argument."
669
- );
670
- err.loc = /** @type {DependencyLocation} */ (arg.loc);
671
- parser.state.module.addWarning(err);
672
- return;
673
- }
674
- const ctx = /** @type {string} */ (evaluated.string).startsWith("file://")
675
- ? fileURLToPath(/** @type {string} */ (evaluated.string))
676
- : /** @type {string} */ (evaluated.string);
677
- // argument always should be a filename
678
- return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
679
- };
680
-
681
- parser.hooks.import.tap(
682
- {
683
- name: PLUGIN_NAME,
684
- stage: -10
685
- },
686
- (statement, source) => {
687
- if (
688
- !moduleName.includes(source) ||
689
- statement.specifiers.length !== 1 ||
690
- statement.specifiers[0].type !== "ImportSpecifier" ||
691
- statement.specifiers[0].imported.type !== "Identifier" ||
692
- statement.specifiers[0].imported.name !== specifierName
693
- ) {
694
- return;
695
- }
696
- // clear for 'import { createRequire as x } from "module"'
697
- // if any other specifier was used import module
698
- const clearDep = new ConstDependency(
699
- parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
700
- ? ";"
701
- : "",
702
- /** @type {Range} */ (statement.range)
703
- );
704
- clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
705
- parser.state.module.addPresentationalDependency(clearDep);
706
- parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
707
- return true;
708
- }
709
- );
710
- parser.hooks.importSpecifier.tap(
711
- {
712
- name: PLUGIN_NAME,
713
- stage: -10
714
- },
715
- (statement, source, id, name) => {
716
- if (!moduleName.includes(source) || id !== specifierName) return;
717
- parser.tagVariable(name, createRequireSpecifierTag);
718
- return true;
719
- }
720
- );
721
- parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
722
- if (
723
- declarator.id.type !== "Identifier" ||
724
- !declarator.init ||
725
- declarator.init.type !== "CallExpression" ||
726
- declarator.init.callee.type !== "Identifier"
727
- ) {
728
- return;
729
- }
730
- const variableInfo = parser.getVariableInfo(declarator.init.callee.name);
731
- if (
732
- variableInfo instanceof VariableInfo &&
733
- variableInfo.tagInfo &&
734
- variableInfo.tagInfo.tag === createRequireSpecifierTag
735
- ) {
736
- const context = parseCreateRequireArguments(declarator.init);
737
- if (context === undefined) return;
738
- parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
739
- name: declarator.id.name,
740
- context
741
- });
742
- return true;
743
- }
744
- });
745
-
746
- parser.hooks.memberChainOfCallMemberChain
747
- .for(createRequireSpecifierTag)
748
- .tap(PLUGIN_NAME, (expr, calleeMembers, callExpr, members) => {
749
- if (
750
- calleeMembers.length !== 0 ||
751
- members.length !== 1 ||
752
- members[0] !== "cache"
753
- ) {
754
- return;
755
- }
756
- // createRequire().cache
757
- const context = parseCreateRequireArguments(callExpr);
758
- if (context === undefined) return;
759
- return requireCache(expr);
760
- });
761
- parser.hooks.callMemberChainOfCallMemberChain
762
- .for(createRequireSpecifierTag)
763
- .tap(PLUGIN_NAME, (expr, calleeMembers, innerCallExpression, members) => {
764
- if (
765
- calleeMembers.length !== 0 ||
766
- members.length !== 1 ||
767
- members[0] !== "resolve"
768
- ) {
769
- return;
770
- }
771
- // createRequire().resolve()
772
- return processResolve(expr, false);
773
- });
774
- parser.hooks.expressionMemberChain
775
- .for(createdRequireIdentifierTag)
776
- .tap(PLUGIN_NAME, (expr, members) => {
777
- // require.cache
778
- if (members.length === 1 && members[0] === "cache") {
779
- return requireCache(expr);
780
- }
781
- });
782
- parser.hooks.callMemberChain
783
- .for(createdRequireIdentifierTag)
784
- .tap(PLUGIN_NAME, (expr, members) => {
785
- // require.resolve()
786
- if (members.length === 1 && members[0] === "resolve") {
787
- return processResolve(expr, false);
788
- }
789
- });
790
- parser.hooks.call
791
- .for(createRequireSpecifierTag)
792
- .tap(PLUGIN_NAME, (expr) => {
793
- const clearDep = new ConstDependency(
794
- "/* createRequire() */ undefined",
795
- /** @type {Range} */ (expr.range)
796
- );
797
- clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
798
- parser.state.module.addPresentationalDependency(clearDep);
799
- return true;
800
- });
801
- // #endregion
802
603
  }
803
604
  }
804
605
 
805
606
  module.exports = CommonJsImportsParserPlugin;
607
+ module.exports.createProcessResolveHandler = createProcessResolveHandler;
608
+ module.exports.createRequireAsExpressionHandler =
609
+ createRequireAsExpressionHandler;
610
+ module.exports.createRequireCacheDependency = createRequireCacheDependency;
611
+ module.exports.createRequireHandler = createRequireCallHandler;