webpack 5.105.2 → 5.105.4

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 (45) hide show
  1. package/lib/CleanPlugin.js +1 -0
  2. package/lib/Compilation.js +10 -8
  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 +45 -5
  11. package/lib/ModuleGraphConnection.js +0 -9
  12. package/lib/MultiStats.js +5 -5
  13. package/lib/RuntimeModule.js +18 -1
  14. package/lib/SourceMapDevToolModuleOptionsPlugin.js +1 -0
  15. package/lib/SourceMapDevToolPlugin.js +10 -2
  16. package/lib/Stats.js +3 -2
  17. package/lib/WebpackOptionsApply.js +13 -3
  18. package/lib/asset/AssetModulesPlugin.js +16 -1
  19. package/lib/asset/RawDataUrlModule.js +5 -1
  20. package/lib/container/RemoteModule.js +18 -1
  21. package/lib/css/CssGenerator.js +13 -6
  22. package/lib/css/CssModulesPlugin.js +7 -0
  23. package/lib/dependencies/CommonJsExportRequireDependency.js +4 -0
  24. package/lib/dependencies/CommonJsImportsParserPlugin.js +314 -508
  25. package/lib/dependencies/CreateRequireParserPlugin.js +356 -0
  26. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +4 -8
  27. package/lib/dependencies/HarmonyImportDependency.js +30 -0
  28. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +128 -224
  29. package/lib/dependencies/HarmonyImportSideEffectDependency.js +11 -5
  30. package/lib/dependencies/HarmonyModulesPlugin.js +4 -0
  31. package/lib/dependencies/ImportParserPlugin.js +1 -11
  32. package/lib/dependencies/ImportPhase.js +4 -0
  33. package/lib/javascript/JavascriptModulesPlugin.js +75 -22
  34. package/lib/javascript/JavascriptParser.js +2 -2
  35. package/lib/optimize/ConcatenatedModule.js +3 -0
  36. package/lib/optimize/ModuleConcatenationPlugin.js +4 -1
  37. package/lib/performance/AssetsOverSizeLimitWarning.js +1 -0
  38. package/lib/performance/EntrypointsOverSizeLimitWarning.js +1 -0
  39. package/lib/performance/SizeLimitsPlugin.js +1 -0
  40. package/lib/runtime/ToBinaryRuntimeModule.js +14 -6
  41. package/lib/sharing/ConsumeSharedModule.js +18 -1
  42. package/lib/util/AppendOnlyStackedSet.js +22 -1
  43. package/lib/util/findGraphRoots.js +79 -109
  44. package/package.json +14 -11
  45. package/types.d.ts +243 -99
@@ -0,0 +1,356 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { fileURLToPath } = require("url");
9
+ const WebpackError = require("../WebpackError");
10
+ const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
11
+ const { VariableInfo } = require("../javascript/JavascriptParser");
12
+ const {
13
+ evaluateToString,
14
+ expressionIsUnsupported,
15
+ toConstantDependency
16
+ } = require("../javascript/JavascriptParserHelpers");
17
+ const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
18
+ const ConstDependency = require("./ConstDependency");
19
+
20
+ /** @typedef {import("estree").CallExpression} CallExpression */
21
+ /** @typedef {import("estree").Expression} Expression */
22
+ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
23
+ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
24
+ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
25
+ /** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
26
+ /** @typedef {import("../javascript/JavascriptParser").Range} Range */
27
+
28
+ /**
29
+ * @typedef {object} CommonJsImportSettings
30
+ * @property {string=} name
31
+ * @property {string} context
32
+ */
33
+
34
+ const createRequireSpecifierTag = Symbol("createRequire");
35
+ const createdRequireIdentifierTag = Symbol("createRequire()");
36
+
37
+ const PLUGIN_NAME = "CreateRequireParserPlugin";
38
+
39
+ const {
40
+ createProcessResolveHandler,
41
+ createRequireAsExpressionHandler,
42
+ createRequireCacheDependency,
43
+ createRequireHandler
44
+ } = CommonJsImportsParserPlugin;
45
+
46
+ class CreateRequireParserPlugin {
47
+ /**
48
+ * @param {JavascriptParserOptions} options parser options
49
+ */
50
+ constructor(options) {
51
+ this.options = options;
52
+ }
53
+
54
+ /**
55
+ * @param {JavascriptParser} parser the parser
56
+ * @returns {void}
57
+ */
58
+ apply(parser) {
59
+ const options = this.options;
60
+ if (!options.createRequire) return;
61
+
62
+ const getContext = () => {
63
+ if (parser.currentTagData) {
64
+ const { context } =
65
+ /** @type {CommonJsImportSettings} */
66
+ (parser.currentTagData);
67
+ return context;
68
+ }
69
+ };
70
+
71
+ /**
72
+ * @param {string | symbol} tag tag
73
+ */
74
+ const tapRequireExpressionTag = (tag) => {
75
+ parser.hooks.typeof
76
+ .for(tag)
77
+ .tap(
78
+ PLUGIN_NAME,
79
+ toConstantDependency(parser, JSON.stringify("function"))
80
+ );
81
+ parser.hooks.evaluateTypeof
82
+ .for(tag)
83
+ .tap(PLUGIN_NAME, evaluateToString("function"));
84
+ };
85
+
86
+ /**
87
+ * @param {Expression} expr expression
88
+ * @returns {boolean} true when set undefined
89
+ */
90
+ const defineUndefined = (expr) => {
91
+ const dep = new ConstDependency(
92
+ "undefined",
93
+ /** @type {Range} */ (expr.range)
94
+ );
95
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
96
+ parser.state.module.addPresentationalDependency(dep);
97
+ return false;
98
+ };
99
+
100
+ const requireCache = createRequireCacheDependency(parser);
101
+ const requireAsExpressionHandler = createRequireAsExpressionHandler(
102
+ parser,
103
+ options,
104
+ getContext
105
+ );
106
+ const createRequireCallHandler = createRequireHandler(
107
+ parser,
108
+ options,
109
+ getContext
110
+ );
111
+ const processResolve = createProcessResolveHandler(
112
+ parser,
113
+ options,
114
+ getContext
115
+ );
116
+
117
+ /** @type {ImportSource[]} */
118
+ let moduleNames = [];
119
+ /** @type {string | undefined} */
120
+ let specifierName;
121
+
122
+ if (options.createRequire === true) {
123
+ moduleNames = ["module", "node:module"];
124
+ specifierName = "createRequire";
125
+ } else if (typeof options.createRequire === "string") {
126
+ /** @type {undefined | string} */
127
+ let parsedModuleName;
128
+ const match = /^(.*) from (.*)$/.exec(options.createRequire);
129
+ if (match) {
130
+ [, specifierName, parsedModuleName] = match;
131
+ }
132
+ if (!specifierName || !parsedModuleName) {
133
+ const err = new WebpackError(
134
+ `Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
135
+ options.createRequire
136
+ )}`
137
+ );
138
+ err.details =
139
+ 'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
140
+ throw err;
141
+ }
142
+ moduleNames = [parsedModuleName];
143
+ } else {
144
+ return;
145
+ }
146
+
147
+ /**
148
+ * @param {CallExpression} expr call expression
149
+ * @returns {string | void} context
150
+ */
151
+ const parseCreateRequireArguments = (expr) => {
152
+ const args = expr.arguments;
153
+ if (args.length !== 1) {
154
+ const err = new WebpackError(
155
+ "module.createRequire supports only one argument."
156
+ );
157
+ err.loc = /** @type {DependencyLocation} */ (expr.loc);
158
+ parser.state.module.addWarning(err);
159
+ return;
160
+ }
161
+ const arg = args[0];
162
+ const evaluated = parser.evaluateExpression(arg);
163
+ if (!evaluated.isString()) {
164
+ const err = new WebpackError(
165
+ "module.createRequire failed parsing argument."
166
+ );
167
+ err.loc = /** @type {DependencyLocation} */ (arg.loc);
168
+ parser.state.module.addWarning(err);
169
+ return;
170
+ }
171
+ const ctx = /** @type {string} */ (evaluated.string).startsWith("file://")
172
+ ? fileURLToPath(/** @type {string} */ (evaluated.string))
173
+ : /** @type {string} */ (evaluated.string);
174
+ // argument always should be a filename
175
+ return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
176
+ };
177
+
178
+ tapRequireExpressionTag(createdRequireIdentifierTag);
179
+ tapRequireExpressionTag(createRequireSpecifierTag);
180
+
181
+ parser.hooks.evaluateCallExpression
182
+ .for(createRequireSpecifierTag)
183
+ .tap(PLUGIN_NAME, (expr) => {
184
+ const context = parseCreateRequireArguments(expr);
185
+ if (context === undefined) return;
186
+ const ident = parser.evaluatedVariable({
187
+ tag: createdRequireIdentifierTag,
188
+ data: { context },
189
+ next: undefined
190
+ });
191
+
192
+ return new BasicEvaluatedExpression()
193
+ .setIdentifier(ident, ident, () => [])
194
+ .setSideEffects(false)
195
+ .setRange(/** @type {Range} */ (expr.range));
196
+ });
197
+
198
+ parser.hooks.unhandledExpressionMemberChain
199
+ .for(createdRequireIdentifierTag)
200
+ .tap(PLUGIN_NAME, (expr, members) =>
201
+ expressionIsUnsupported(
202
+ parser,
203
+ `createRequire().${members.join(".")} is not supported by webpack.`
204
+ )(expr)
205
+ );
206
+ parser.hooks.canRename
207
+ .for(createdRequireIdentifierTag)
208
+ .tap(PLUGIN_NAME, () => true);
209
+ parser.hooks.canRename
210
+ .for(createRequireSpecifierTag)
211
+ .tap(PLUGIN_NAME, () => true);
212
+ parser.hooks.rename
213
+ .for(createRequireSpecifierTag)
214
+ .tap(PLUGIN_NAME, defineUndefined);
215
+ parser.hooks.expression
216
+ .for(createdRequireIdentifierTag)
217
+ .tap(PLUGIN_NAME, requireAsExpressionHandler);
218
+ parser.hooks.call
219
+ .for(createdRequireIdentifierTag)
220
+ .tap(PLUGIN_NAME, createRequireCallHandler(false));
221
+
222
+ parser.hooks.import.tap(
223
+ {
224
+ name: PLUGIN_NAME,
225
+ stage: -10
226
+ },
227
+ (statement, source) => {
228
+ if (
229
+ !moduleNames.includes(source) ||
230
+ statement.specifiers.length !== 1 ||
231
+ statement.specifiers[0].type !== "ImportSpecifier" ||
232
+ statement.specifiers[0].imported.type !== "Identifier" ||
233
+ statement.specifiers[0].imported.name !== specifierName
234
+ ) {
235
+ return;
236
+ }
237
+ // clear for 'import { createRequire as x } from "module"'
238
+ // if any other specifier was used import module
239
+ const clearDep = new ConstDependency(
240
+ parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
241
+ ? ";"
242
+ : "",
243
+ /** @type {Range} */ (statement.range)
244
+ );
245
+ clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
246
+ parser.state.module.addPresentationalDependency(clearDep);
247
+ parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
248
+ return true;
249
+ }
250
+ );
251
+ parser.hooks.importSpecifier.tap(
252
+ {
253
+ name: PLUGIN_NAME,
254
+ stage: -10
255
+ },
256
+ (statement, source, id, name) => {
257
+ if (!moduleNames.includes(source) || id !== specifierName) return;
258
+ parser.tagVariable(name, createRequireSpecifierTag);
259
+ return true;
260
+ }
261
+ );
262
+ parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
263
+ if (
264
+ declarator.id.type !== "Identifier" ||
265
+ !declarator.init ||
266
+ declarator.init.type !== "CallExpression" ||
267
+ declarator.init.callee.type !== "Identifier"
268
+ ) {
269
+ return;
270
+ }
271
+ const variableInfo = parser.getVariableInfo(declarator.init.callee.name);
272
+ if (
273
+ variableInfo instanceof VariableInfo &&
274
+ variableInfo.tagInfo &&
275
+ variableInfo.tagInfo.tag === createRequireSpecifierTag
276
+ ) {
277
+ const context = parseCreateRequireArguments(declarator.init);
278
+ if (context === undefined) return;
279
+ parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
280
+ name: declarator.id.name,
281
+ context
282
+ });
283
+ return true;
284
+ }
285
+ });
286
+
287
+ parser.hooks.memberChainOfCallMemberChain
288
+ .for(createRequireSpecifierTag)
289
+ .tap(PLUGIN_NAME, (expr, calleeMembers, callExpr, members) => {
290
+ if (
291
+ calleeMembers.length !== 0 ||
292
+ members.length !== 1 ||
293
+ members[0] !== "cache"
294
+ ) {
295
+ return;
296
+ }
297
+ // createRequire().cache
298
+ const context = parseCreateRequireArguments(callExpr);
299
+ if (context === undefined) return;
300
+ return requireCache(expr);
301
+ });
302
+ parser.hooks.callMemberChainOfCallMemberChain
303
+ .for(createRequireSpecifierTag)
304
+ .tap(PLUGIN_NAME, (expr, calleeMembers, innerCallExpression, members) => {
305
+ if (
306
+ calleeMembers.length !== 0 ||
307
+ members.length !== 1 ||
308
+ members[0] !== "resolve"
309
+ ) {
310
+ return;
311
+ }
312
+ // createRequire().resolve()
313
+ return processResolve(expr, false);
314
+ });
315
+ parser.hooks.expressionMemberChain
316
+ .for(createdRequireIdentifierTag)
317
+ .tap(PLUGIN_NAME, (expr, members) => {
318
+ // require.cache
319
+ if (members.length === 1 && members[0] === "cache") {
320
+ return requireCache(expr);
321
+ }
322
+ });
323
+ parser.hooks.callMemberChain
324
+ .for(createdRequireIdentifierTag)
325
+ .tap(PLUGIN_NAME, (expr, members) => {
326
+ // require.resolve()
327
+ if (members.length === 1 && members[0] === "resolve") {
328
+ return processResolve(expr, false);
329
+ }
330
+ });
331
+ parser.hooks.expression
332
+ .for(createRequireSpecifierTag)
333
+ .tap(PLUGIN_NAME, (expr) => {
334
+ const clearDep = new ConstDependency(
335
+ "/* createRequire */ undefined",
336
+ /** @type {Range} */ (expr.range)
337
+ );
338
+ clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
339
+ parser.state.module.addPresentationalDependency(clearDep);
340
+ return true;
341
+ });
342
+ parser.hooks.call
343
+ .for(createRequireSpecifierTag)
344
+ .tap(PLUGIN_NAME, (expr) => {
345
+ const clearDep = new ConstDependency(
346
+ "/* createRequire() */ undefined",
347
+ /** @type {Range} */ (expr.range)
348
+ );
349
+ clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
350
+ parser.state.module.addPresentationalDependency(clearDep);
351
+ return true;
352
+ });
353
+ }
354
+ }
355
+
356
+ module.exports = CreateRequireParserPlugin;
@@ -39,14 +39,10 @@ module.exports = class HarmonyExportDependencyParserPlugin {
39
39
  */
40
40
  constructor(options) {
41
41
  this.options = options;
42
- this.exportPresenceMode =
43
- options.reexportExportsPresence !== undefined
44
- ? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
45
- : options.exportsPresence !== undefined
46
- ? ExportPresenceModes.fromUserOption(options.exportsPresence)
47
- : options.strictExportPresence
48
- ? ExportPresenceModes.ERROR
49
- : ExportPresenceModes.AUTO;
42
+ this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
43
+ options.reexportExportsPresence,
44
+ options
45
+ );
50
46
  }
51
47
 
52
48
  /**
@@ -53,9 +53,38 @@ const ExportPresenceModes = {
53
53
  default:
54
54
  throw new Error(`Invalid export presence value ${str}`);
55
55
  }
56
+ },
57
+ /**
58
+ * Resolve export presence mode from parser options with a specific key and shared fallbacks.
59
+ * @param {string | false | undefined} specificValue the type-specific option value (e.g. importExportsPresence or reexportExportsPresence)
60
+ * @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options parser options
61
+ * @returns {ExportPresenceMode} resolved mode
62
+ */
63
+ resolveFromOptions(specificValue, options) {
64
+ if (specificValue !== undefined) {
65
+ return ExportPresenceModes.fromUserOption(specificValue);
66
+ }
67
+ if (options.exportsPresence !== undefined) {
68
+ return ExportPresenceModes.fromUserOption(options.exportsPresence);
69
+ }
70
+ return options.strictExportPresence
71
+ ? ExportPresenceModes.ERROR
72
+ : ExportPresenceModes.AUTO;
56
73
  }
57
74
  };
58
75
 
76
+ /**
77
+ * Get the non-optional leading part of a member chain.
78
+ * @param {string[]} members members
79
+ * @param {boolean[]} membersOptionals optionality for each member
80
+ * @returns {string[]} the non-optional prefix
81
+ */
82
+ const getNonOptionalPart = (members, membersOptionals) => {
83
+ let i = 0;
84
+ while (i < members.length && membersOptionals[i] === false) i++;
85
+ return i !== members.length ? members.slice(0, i) : members;
86
+ };
87
+
59
88
  /** @typedef {string[]} Ids */
60
89
 
61
90
  class HarmonyImportDependency extends ModuleDependency {
@@ -427,3 +456,4 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
427
456
  };
428
457
 
429
458
  module.exports.ExportPresenceModes = ExportPresenceModes;
459
+ module.exports.getNonOptionalPart = getNonOptionalPart;