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.
- package/lib/CleanPlugin.js +1 -0
- package/lib/Compilation.js +8 -6
- package/lib/ContextModule.js +14 -8
- package/lib/Dependency.js +1 -1
- package/lib/EnvironmentNotSupportAsyncWarning.js +1 -0
- package/lib/EvalDevToolModulePlugin.js +3 -0
- package/lib/EvalSourceMapDevToolPlugin.js +8 -1
- package/lib/ExportsInfo.js +0 -30
- package/lib/ExternalModule.js +2 -2
- package/lib/Module.js +30 -5
- package/lib/ModuleGraphConnection.js +0 -9
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +1 -0
- package/lib/SourceMapDevToolPlugin.js +10 -2
- package/lib/WebpackOptionsApply.js +13 -3
- package/lib/asset/AssetModulesPlugin.js +16 -1
- package/lib/asset/RawDataUrlModule.js +5 -1
- package/lib/css/CssGenerator.js +3 -6
- package/lib/css/CssModulesPlugin.js +7 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +4 -0
- package/lib/dependencies/CommonJsImportsParserPlugin.js +314 -508
- package/lib/dependencies/CreateRequireParserPlugin.js +345 -0
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +4 -8
- package/lib/dependencies/HarmonyImportDependency.js +30 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -20
- package/lib/dependencies/HarmonyModulesPlugin.js +4 -0
- package/lib/dependencies/ImportParserPlugin.js +1 -11
- package/lib/dependencies/ImportPhase.js +4 -0
- package/lib/javascript/JavascriptModulesPlugin.js +75 -22
- package/lib/javascript/JavascriptParser.js +2 -2
- package/lib/performance/AssetsOverSizeLimitWarning.js +1 -0
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +1 -0
- package/lib/performance/SizeLimitsPlugin.js +1 -0
- package/lib/runtime/ToBinaryRuntimeModule.js +14 -6
- package/lib/util/findGraphRoots.js +79 -109
- package/package.json +12 -9
- package/types.d.ts +147 -62
|
@@ -0,0 +1,345 @@
|
|
|
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.call
|
|
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
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
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
|
|
44
|
-
|
|
45
|
-
|
|
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;
|
|
@@ -18,7 +18,10 @@ const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
|
|
18
18
|
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
|
19
19
|
const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
|
|
20
20
|
const HarmonyExports = require("./HarmonyExports");
|
|
21
|
-
const {
|
|
21
|
+
const {
|
|
22
|
+
ExportPresenceModes,
|
|
23
|
+
getNonOptionalPart
|
|
24
|
+
} = require("./HarmonyImportDependency");
|
|
22
25
|
const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
|
|
23
26
|
const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
|
|
24
27
|
const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
|
|
@@ -82,14 +85,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
|
|
82
85
|
constructor(options) {
|
|
83
86
|
this.options = options;
|
|
84
87
|
/** @type {ExportPresenceMode} */
|
|
85
|
-
this.exportPresenceMode =
|
|
86
|
-
options.importExportsPresence
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
? ExportPresenceModes.fromUserOption(options.exportsPresence)
|
|
90
|
-
: options.strictExportPresence
|
|
91
|
-
? ExportPresenceModes.ERROR
|
|
92
|
-
: ExportPresenceModes.AUTO;
|
|
88
|
+
this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
|
|
89
|
+
options.importExportsPresence,
|
|
90
|
+
options
|
|
91
|
+
);
|
|
93
92
|
this.strictThisContextOnImports = options.strictThisContextOnImports;
|
|
94
93
|
}
|
|
95
94
|
|
|
@@ -119,17 +118,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
|
|
119
118
|
apply(parser) {
|
|
120
119
|
const getImportPhase = createGetImportPhase(this.options.deferImport);
|
|
121
120
|
|
|
122
|
-
/**
|
|
123
|
-
* @param {Members} members members
|
|
124
|
-
* @param {MembersOptionals} membersOptionals members Optionals
|
|
125
|
-
* @returns {Ids} a non optional part
|
|
126
|
-
*/
|
|
127
|
-
function getNonOptionalPart(members, membersOptionals) {
|
|
128
|
-
let i = 0;
|
|
129
|
-
while (i < members.length && membersOptionals[i] === false) i++;
|
|
130
|
-
return i !== members.length ? members.slice(0, i) : members;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
121
|
/**
|
|
134
122
|
* @param {MemberExpression} node member expression
|
|
135
123
|
* @param {number} count count
|
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
JAVASCRIPT_MODULE_TYPE_AUTO,
|
|
10
10
|
JAVASCRIPT_MODULE_TYPE_ESM
|
|
11
11
|
} = require("../ModuleTypeConstants");
|
|
12
|
+
const CreateRequireParserPlugin = require("./CreateRequireParserPlugin");
|
|
12
13
|
const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
|
13
14
|
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
|
14
15
|
const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
|
|
@@ -138,6 +139,9 @@ class HarmonyModulesPlugin {
|
|
|
138
139
|
new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser);
|
|
139
140
|
new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser);
|
|
140
141
|
new HarmonyTopLevelThisParserPlugin().apply(parser);
|
|
142
|
+
if (parserOptions.createRequire) {
|
|
143
|
+
new CreateRequireParserPlugin(parserOptions).apply(parser);
|
|
144
|
+
}
|
|
141
145
|
};
|
|
142
146
|
|
|
143
147
|
normalModuleFactory.hooks.parser
|
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
} = require("../javascript/JavascriptParser");
|
|
15
15
|
const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
|
|
16
16
|
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
|
17
|
+
const { getNonOptionalPart } = require("./HarmonyImportDependency");
|
|
17
18
|
const ImportContextDependency = require("./ImportContextDependency");
|
|
18
19
|
const ImportDependency = require("./ImportDependency");
|
|
19
20
|
const ImportEagerDependency = require("./ImportEagerDependency");
|
|
@@ -178,17 +179,6 @@ class ImportParserPlugin {
|
|
|
178
179
|
* @returns {void}
|
|
179
180
|
*/
|
|
180
181
|
apply(parser) {
|
|
181
|
-
/**
|
|
182
|
-
* @param {Members} members members
|
|
183
|
-
* @param {MembersOptionals} membersOptionals members Optionals
|
|
184
|
-
* @returns {string[]} a non optional part
|
|
185
|
-
*/
|
|
186
|
-
function getNonOptionalPart(members, membersOptionals) {
|
|
187
|
-
let i = 0;
|
|
188
|
-
while (i < members.length && membersOptionals[i] === false) i++;
|
|
189
|
-
return i !== members.length ? members.slice(0, i) : members;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
182
|
parser.hooks.collectDestructuringAssignmentProperties.tap(
|
|
193
183
|
PLUGIN_NAME,
|
|
194
184
|
(expr) => {
|
|
@@ -27,12 +27,16 @@ const ImportPhase = Object.freeze({
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* @typedef {object} ImportPhaseUtils
|
|
30
|
+
* @property {(phase: ImportPhaseType) => boolean} isEvaluation true if phase is evaluation
|
|
30
31
|
* @property {(phase: ImportPhaseType) => boolean} isDefer true if phase is defer
|
|
31
32
|
* @property {(phase: ImportPhaseType) => boolean} isSource true if phase is source
|
|
32
33
|
*/
|
|
33
34
|
|
|
34
35
|
/** @type {ImportPhaseUtils} */
|
|
35
36
|
const ImportPhaseUtils = {
|
|
37
|
+
isEvaluation(phase) {
|
|
38
|
+
return phase === ImportPhase.Evaluation;
|
|
39
|
+
},
|
|
36
40
|
isDefer(phase) {
|
|
37
41
|
return phase === ImportPhase.Defer;
|
|
38
42
|
},
|
|
@@ -56,6 +56,7 @@ const JavascriptParser = require("./JavascriptParser");
|
|
|
56
56
|
/** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
|
|
57
57
|
/** @typedef {import("../Chunk")} Chunk */
|
|
58
58
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
|
59
|
+
/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
|
|
59
60
|
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
|
|
60
61
|
/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
|
|
61
62
|
/** @typedef {import("../Compilation").ExecuteModuleObject} ExecuteModuleObject */
|
|
@@ -75,37 +76,75 @@ const JavascriptParser = require("./JavascriptParser");
|
|
|
75
76
|
/** @typedef {import("../util/concatenate").ScopeSet} ScopeSet */
|
|
76
77
|
/** @typedef {import("../util/concatenate").UsedNamesInScopeInfo} UsedNamesInScopeInfo */
|
|
77
78
|
|
|
79
|
+
/** @type {WeakMap<ChunkGraph, WeakMap<Chunk, boolean>>} */
|
|
80
|
+
const chunkHasJsCache = new WeakMap();
|
|
81
|
+
|
|
78
82
|
/**
|
|
79
83
|
* @param {Chunk} chunk a chunk
|
|
80
84
|
* @param {ChunkGraph} chunkGraph the chunk graph
|
|
81
85
|
* @returns {boolean} true, when a JS file is needed for this chunk
|
|
82
86
|
*/
|
|
83
|
-
const
|
|
84
|
-
if (chunkGraph.getNumberOfEntryModules(chunk) > 0)
|
|
87
|
+
const _chunkHasJs = (chunk, chunkGraph) => {
|
|
88
|
+
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
|
89
|
+
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
|
|
90
|
+
if (chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
85
95
|
|
|
86
96
|
return Boolean(
|
|
87
97
|
chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
|
|
88
98
|
);
|
|
89
99
|
};
|
|
90
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @param {Chunk} chunk a chunk
|
|
103
|
+
* @param {ChunkGraph} chunkGraph the chunk graph
|
|
104
|
+
* @returns {boolean} true, when a JS file is needed for this chunk
|
|
105
|
+
*/
|
|
106
|
+
const chunkHasJs = (chunk, chunkGraph) => {
|
|
107
|
+
let innerCache = chunkHasJsCache.get(chunkGraph);
|
|
108
|
+
if (innerCache === undefined) {
|
|
109
|
+
innerCache = new WeakMap();
|
|
110
|
+
chunkHasJsCache.set(chunkGraph, innerCache);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const cachedResult = innerCache.get(chunk);
|
|
114
|
+
if (cachedResult !== undefined) {
|
|
115
|
+
return cachedResult;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const result = _chunkHasJs(chunk, chunkGraph);
|
|
119
|
+
innerCache.set(chunk, result);
|
|
120
|
+
return result;
|
|
121
|
+
};
|
|
122
|
+
|
|
91
123
|
/**
|
|
92
124
|
* @param {Chunk} chunk a chunk
|
|
93
125
|
* @param {ChunkGraph} chunkGraph the chunk graph
|
|
94
126
|
* @returns {boolean} true, when a JS file is needed for this chunk
|
|
95
127
|
*/
|
|
96
128
|
const chunkHasRuntimeOrJs = (chunk, chunkGraph) => {
|
|
129
|
+
if (chunkHasJs(chunk, chunkGraph)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
97
133
|
if (
|
|
98
134
|
chunkGraph.getChunkModulesIterableBySourceType(
|
|
99
135
|
chunk,
|
|
100
136
|
WEBPACK_MODULE_TYPE_RUNTIME
|
|
101
137
|
)
|
|
102
138
|
) {
|
|
103
|
-
|
|
139
|
+
for (const chunkGroup of chunk.groupsIterable) {
|
|
140
|
+
for (const c of chunkGroup.chunks) {
|
|
141
|
+
if (chunkHasJs(c, chunkGraph)) return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
104
145
|
}
|
|
105
146
|
|
|
106
|
-
return
|
|
107
|
-
chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
|
|
108
|
-
);
|
|
147
|
+
return false;
|
|
109
148
|
};
|
|
110
149
|
|
|
111
150
|
/**
|
|
@@ -1312,17 +1351,22 @@ class JavascriptModulesPlugin {
|
|
|
1312
1351
|
const runtimeRequirements =
|
|
1313
1352
|
chunkGraph.getTreeRuntimeRequirements(chunk);
|
|
1314
1353
|
buf2.push("// Load entry module and return exports");
|
|
1315
|
-
|
|
1354
|
+
|
|
1355
|
+
/** @type {EntryModuleWithChunkGroup[]} */
|
|
1356
|
+
const jsEntries = [];
|
|
1316
1357
|
for (const [
|
|
1317
1358
|
entryModule,
|
|
1318
1359
|
entrypoint
|
|
1319
1360
|
] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
|
|
1320
1361
|
if (
|
|
1321
|
-
|
|
1362
|
+
chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
|
|
1322
1363
|
) {
|
|
1323
|
-
|
|
1364
|
+
jsEntries.push([entryModule, entrypoint]);
|
|
1324
1365
|
continue;
|
|
1325
1366
|
}
|
|
1367
|
+
}
|
|
1368
|
+
let i = jsEntries.length;
|
|
1369
|
+
for (const [entryModule, entrypoint] of jsEntries) {
|
|
1326
1370
|
const chunks =
|
|
1327
1371
|
/** @type {Entrypoint} */
|
|
1328
1372
|
(entrypoint).chunks.filter((c) => c !== chunk);
|
|
@@ -1546,20 +1590,42 @@ class JavascriptModulesPlugin {
|
|
|
1546
1590
|
runtimeTemplate: { outputOptions }
|
|
1547
1591
|
} = renderContext;
|
|
1548
1592
|
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* @param {string} condition guard expression
|
|
1596
|
+
* @returns {string[]} source
|
|
1597
|
+
*/
|
|
1598
|
+
const renderMissingModuleError = (condition) =>
|
|
1599
|
+
outputOptions.pathinfo
|
|
1600
|
+
? [
|
|
1601
|
+
`if (${condition}) {`,
|
|
1602
|
+
Template.indent([
|
|
1603
|
+
"delete __webpack_module_cache__[moduleId];",
|
|
1604
|
+
'var e = new Error("Cannot find module \'" + moduleId + "\'");',
|
|
1605
|
+
"e.code = 'MODULE_NOT_FOUND';",
|
|
1606
|
+
"throw e;"
|
|
1607
|
+
]),
|
|
1608
|
+
"}"
|
|
1609
|
+
]
|
|
1610
|
+
: [];
|
|
1611
|
+
|
|
1549
1612
|
const moduleExecution = runtimeRequirements.has(
|
|
1550
1613
|
RuntimeGlobals.interceptModuleExecution
|
|
1551
1614
|
)
|
|
1552
1615
|
? Template.asString([
|
|
1553
1616
|
`var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`,
|
|
1554
1617
|
`${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
|
|
1618
|
+
...renderMissingModuleError("!execOptions.factory"),
|
|
1555
1619
|
"module = execOptions.module;",
|
|
1556
1620
|
"execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
|
|
1557
1621
|
])
|
|
1558
1622
|
: runtimeRequirements.has(RuntimeGlobals.thisAsExports)
|
|
1559
1623
|
? Template.asString([
|
|
1624
|
+
...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
|
|
1560
1625
|
`__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});`
|
|
1561
1626
|
])
|
|
1562
1627
|
: Template.asString([
|
|
1628
|
+
...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
|
|
1563
1629
|
`__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});`
|
|
1564
1630
|
]);
|
|
1565
1631
|
const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
|
|
@@ -1580,19 +1646,6 @@ class JavascriptModulesPlugin {
|
|
|
1580
1646
|
])
|
|
1581
1647
|
: Template.indent("return cachedModule.exports;"),
|
|
1582
1648
|
"}",
|
|
1583
|
-
// Add helpful error message in development mode when module is not found
|
|
1584
|
-
...(outputOptions.pathinfo
|
|
1585
|
-
? [
|
|
1586
|
-
"// Check if module exists (development only)",
|
|
1587
|
-
"if (__webpack_modules__[moduleId] === undefined) {",
|
|
1588
|
-
Template.indent([
|
|
1589
|
-
'var e = new Error("Cannot find module \'" + moduleId + "\'");',
|
|
1590
|
-
"e.code = 'MODULE_NOT_FOUND';",
|
|
1591
|
-
"throw e;"
|
|
1592
|
-
]),
|
|
1593
|
-
"}"
|
|
1594
|
-
]
|
|
1595
|
-
: []),
|
|
1596
1649
|
"// Create a new module (and put it into the cache)",
|
|
1597
1650
|
"var module = __webpack_module_cache__[moduleId] = {",
|
|
1598
1651
|
Template.indent([
|