webpack 5.88.2 → 5.89.0
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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/lib/dependencies/CommonJsFullRequireDependency.js +27 -6
- package/lib/dependencies/CommonJsImportsParserPlugin.js +20 -4
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +13 -63
- package/lib/javascript/JavascriptParser.js +10 -6
- package/lib/util/chainedImports.js +96 -0
- package/package.json +1 -1
- package/types.d.ts +8 -2
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
const Template = require("../Template");
|
9
9
|
const { equals } = require("../util/ArrayHelpers");
|
10
|
+
const { getTrimmedIdsAndRange } = require("../util/chainedImports");
|
10
11
|
const makeSerializable = require("../util/makeSerializable");
|
11
12
|
const propertyAccess = require("../util/propertyAccess");
|
12
13
|
const ModuleDependency = require("./ModuleDependency");
|
@@ -26,11 +27,18 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
26
27
|
* @param {string} request the request string
|
27
28
|
* @param {Range} range location in source code
|
28
29
|
* @param {string[]} names accessed properties on module
|
30
|
+
* @param {Range[]=} idRanges ranges for members of ids; the two arrays are right-aligned
|
29
31
|
*/
|
30
|
-
constructor(
|
32
|
+
constructor(
|
33
|
+
request,
|
34
|
+
range,
|
35
|
+
names,
|
36
|
+
idRanges /* TODO webpack 6 make this non-optional. It must always be set to properly trim ids. */
|
37
|
+
) {
|
31
38
|
super(request);
|
32
39
|
this.range = range;
|
33
40
|
this.names = names;
|
41
|
+
this.idRanges = idRanges;
|
34
42
|
this.call = false;
|
35
43
|
this.asiSafe = undefined;
|
36
44
|
}
|
@@ -60,6 +68,7 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
60
68
|
serialize(context) {
|
61
69
|
const { write } = context;
|
62
70
|
write(this.names);
|
71
|
+
write(this.idRanges);
|
63
72
|
write(this.call);
|
64
73
|
write(this.asiSafe);
|
65
74
|
super.serialize(context);
|
@@ -71,6 +80,7 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
71
80
|
deserialize(context) {
|
72
81
|
const { read } = context;
|
73
82
|
this.names = read();
|
83
|
+
this.idRanges = read();
|
74
84
|
this.call = read();
|
75
85
|
this.asiSafe = read();
|
76
86
|
super.deserialize(context);
|
@@ -117,15 +127,26 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
|
|
117
127
|
weak: dep.weak,
|
118
128
|
runtimeRequirements
|
119
129
|
});
|
130
|
+
|
131
|
+
const {
|
132
|
+
trimmedRange: [trimmedRangeStart, trimmedRangeEnd],
|
133
|
+
trimmedIds
|
134
|
+
} = getTrimmedIdsAndRange(
|
135
|
+
dep.names,
|
136
|
+
dep.range,
|
137
|
+
dep.idRanges,
|
138
|
+
moduleGraph,
|
139
|
+
dep
|
140
|
+
);
|
141
|
+
|
120
142
|
if (importedModule) {
|
121
|
-
const ids = dep.names;
|
122
143
|
const usedImported = moduleGraph
|
123
144
|
.getExportsInfo(importedModule)
|
124
|
-
.getUsedName(
|
145
|
+
.getUsedName(trimmedIds, runtime);
|
125
146
|
if (usedImported) {
|
126
|
-
const comment = equals(usedImported,
|
147
|
+
const comment = equals(usedImported, trimmedIds)
|
127
148
|
? ""
|
128
|
-
: Template.toNormalComment(propertyAccess(
|
149
|
+
: Template.toNormalComment(propertyAccess(trimmedIds)) + " ";
|
129
150
|
const access = `${comment}${propertyAccess(usedImported)}`;
|
130
151
|
requireExpr =
|
131
152
|
dep.asiSafe === true
|
@@ -133,7 +154,7 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
|
|
133
154
|
: `${requireExpr}${access}`;
|
134
155
|
}
|
135
156
|
}
|
136
|
-
source.replace(
|
157
|
+
source.replace(trimmedRangeStart, trimmedRangeEnd - 1, requireExpr);
|
137
158
|
}
|
138
159
|
};
|
139
160
|
|
@@ -379,9 +379,16 @@ class CommonJsImportsParserPlugin {
|
|
379
379
|
* @param {string[]} calleeMembers callee members
|
380
380
|
* @param {CallExpression} callExpr call expression
|
381
381
|
* @param {string[]} members members
|
382
|
+
* @param {Range[]} memberRanges member ranges
|
382
383
|
* @returns {boolean | void} true when handled
|
383
384
|
*/
|
384
|
-
const chainHandler = (
|
385
|
+
const chainHandler = (
|
386
|
+
expr,
|
387
|
+
calleeMembers,
|
388
|
+
callExpr,
|
389
|
+
members,
|
390
|
+
memberRanges
|
391
|
+
) => {
|
385
392
|
if (callExpr.arguments.length !== 1) return;
|
386
393
|
const param = parser.evaluateExpression(callExpr.arguments[0]);
|
387
394
|
if (
|
@@ -391,7 +398,8 @@ class CommonJsImportsParserPlugin {
|
|
391
398
|
const dep = new CommonJsFullRequireDependency(
|
392
399
|
/** @type {string} */ (param.string),
|
393
400
|
/** @type {Range} */ (expr.range),
|
394
|
-
members
|
401
|
+
members,
|
402
|
+
/** @type {Range[]} */ memberRanges
|
395
403
|
);
|
396
404
|
dep.asiSafe = !parser.isAsiPosition(
|
397
405
|
/** @type {Range} */ (expr.range)[0]
|
@@ -407,9 +415,16 @@ class CommonJsImportsParserPlugin {
|
|
407
415
|
* @param {string[]} calleeMembers callee members
|
408
416
|
* @param {CallExpression} callExpr call expression
|
409
417
|
* @param {string[]} members members
|
418
|
+
* @param {Range[]} memberRanges member ranges
|
410
419
|
* @returns {boolean | void} true when handled
|
411
420
|
*/
|
412
|
-
const callChainHandler = (
|
421
|
+
const callChainHandler = (
|
422
|
+
expr,
|
423
|
+
calleeMembers,
|
424
|
+
callExpr,
|
425
|
+
members,
|
426
|
+
memberRanges
|
427
|
+
) => {
|
413
428
|
if (callExpr.arguments.length !== 1) return;
|
414
429
|
const param = parser.evaluateExpression(callExpr.arguments[0]);
|
415
430
|
if (
|
@@ -419,7 +434,8 @@ class CommonJsImportsParserPlugin {
|
|
419
434
|
const dep = new CommonJsFullRequireDependency(
|
420
435
|
/** @type {string} */ (param.string),
|
421
436
|
/** @type {Range} */ (expr.callee.range),
|
422
|
-
members
|
437
|
+
members,
|
438
|
+
/** @type {Range[]} */ memberRanges
|
423
439
|
);
|
424
440
|
dep.call = true;
|
425
441
|
dep.asiSafe = !parser.isAsiPosition(
|
@@ -9,6 +9,7 @@ const Dependency = require("../Dependency");
|
|
9
9
|
const {
|
10
10
|
getDependencyUsedByExportsCondition
|
11
11
|
} = require("../optimize/InnerGraph");
|
12
|
+
const { getTrimmedIdsAndRange } = require("../util/chainedImports");
|
12
13
|
const makeSerializable = require("../util/makeSerializable");
|
13
14
|
const propertyAccess = require("../util/propertyAccess");
|
14
15
|
const HarmonyImportDependency = require("./HarmonyImportDependency");
|
@@ -324,30 +325,16 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|
324
325
|
// Skip rendering depending when dependency is conditional
|
325
326
|
if (connection && !connection.isTargetActive(runtime)) return;
|
326
327
|
|
327
|
-
const
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
dep.idRanges === undefined
|
338
|
-
? -1 /* trigger failure case below */
|
339
|
-
: dep.idRanges.length + (trimmedIds.length - ids.length);
|
340
|
-
if (idx < 0 || idx >= dep.idRanges.length) {
|
341
|
-
// cspell:ignore minifiers
|
342
|
-
// Should not happen but we can't throw an error here because of backward compatibility with
|
343
|
-
// external plugins in wp5. Instead, we just disable trimming for now. This may break some minifiers.
|
344
|
-
trimmedIds = ids;
|
345
|
-
// TODO webpack 6 remove the "trimmedIds = ids" above and uncomment the following line instead.
|
346
|
-
// throw new Error("Missing range starts data for id replacement trimming.");
|
347
|
-
} else {
|
348
|
-
[rangeStart, rangeEnd] = dep.idRanges[idx];
|
349
|
-
}
|
350
|
-
}
|
328
|
+
const {
|
329
|
+
trimmedRange: [trimmedRangeStart, trimmedRangeEnd],
|
330
|
+
trimmedIds
|
331
|
+
} = getTrimmedIdsAndRange(
|
332
|
+
dep.getIds(moduleGraph),
|
333
|
+
dep.range,
|
334
|
+
dep.idRanges,
|
335
|
+
moduleGraph,
|
336
|
+
dep
|
337
|
+
);
|
351
338
|
|
352
339
|
const exportExpr = this._getCodeForIds(
|
353
340
|
dep,
|
@@ -356,47 +343,10 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|
356
343
|
trimmedIds
|
357
344
|
);
|
358
345
|
if (dep.shorthand) {
|
359
|
-
source.insert(
|
346
|
+
source.insert(trimmedRangeEnd, `: ${exportExpr}`);
|
360
347
|
} else {
|
361
|
-
source.replace(
|
362
|
-
}
|
363
|
-
}
|
364
|
-
|
365
|
-
/**
|
366
|
-
* @summary Determine which IDs in the id chain are actually referring to namespaces or imports,
|
367
|
-
* and which are deeper member accessors on the imported object. Only the former should be re-rendered.
|
368
|
-
* @param {string[]} ids ids
|
369
|
-
* @param {ModuleGraph} moduleGraph moduleGraph
|
370
|
-
* @param {HarmonyImportSpecifierDependency} dependency dependency
|
371
|
-
* @returns {string[]} generated code
|
372
|
-
*/
|
373
|
-
_trimIdsToThoseImported(ids, moduleGraph, dependency) {
|
374
|
-
/** @type {string[]} */
|
375
|
-
let trimmedIds = [];
|
376
|
-
const exportsInfo = moduleGraph.getExportsInfo(
|
377
|
-
/** @type {Module} */ (moduleGraph.getModule(dependency))
|
378
|
-
);
|
379
|
-
let currentExportsInfo = /** @type {ExportsInfo=} */ exportsInfo;
|
380
|
-
for (let i = 0; i < ids.length; i++) {
|
381
|
-
if (i === 0 && ids[i] === "default") {
|
382
|
-
continue; // ExportInfo for the next level under default is still at the root ExportsInfo, so don't advance currentExportsInfo
|
383
|
-
}
|
384
|
-
const exportInfo = currentExportsInfo.getExportInfo(ids[i]);
|
385
|
-
if (exportInfo.provided === false) {
|
386
|
-
// json imports have nested ExportInfo for elements that things that are not actually exported, so check .provided
|
387
|
-
trimmedIds = ids.slice(0, i);
|
388
|
-
break;
|
389
|
-
}
|
390
|
-
const nestedInfo = exportInfo.getNestedExportsInfo();
|
391
|
-
if (!nestedInfo) {
|
392
|
-
// once all nested exports are traversed, the next item is the actual import so stop there
|
393
|
-
trimmedIds = ids.slice(0, i + 1);
|
394
|
-
break;
|
395
|
-
}
|
396
|
-
currentExportsInfo = nestedInfo;
|
348
|
+
source.replace(trimmedRangeStart, trimmedRangeEnd - 1, exportExpr);
|
397
349
|
}
|
398
|
-
// Never trim to nothing. This can happen for invalid imports (e.g. import { notThere } from "./module", or import { anything } from "./missingModule")
|
399
|
-
return trimmedIds.length ? trimmedIds : ids;
|
400
350
|
}
|
401
351
|
|
402
352
|
/**
|
@@ -363,25 +363,27 @@ class JavascriptParser extends Parser {
|
|
363
363
|
])
|
364
364
|
),
|
365
365
|
/** Something like "a.b().c.d" */
|
366
|
-
/** @type {HookMap<SyncBailHook<[Expression, string[], CallExpression, string[]], boolean | void>>} */
|
366
|
+
/** @type {HookMap<SyncBailHook<[Expression, string[], CallExpression, string[], Range[]], boolean | void>>} */
|
367
367
|
memberChainOfCallMemberChain: new HookMap(
|
368
368
|
() =>
|
369
369
|
new SyncBailHook([
|
370
370
|
"expression",
|
371
371
|
"calleeMembers",
|
372
372
|
"callExpression",
|
373
|
-
"members"
|
373
|
+
"members",
|
374
|
+
"memberRanges"
|
374
375
|
])
|
375
376
|
),
|
376
377
|
/** Something like "a.b().c.d()"" */
|
377
|
-
/** @type {HookMap<SyncBailHook<[CallExpression, string[], CallExpression, string[]], boolean | void>>} */
|
378
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, string[], CallExpression, string[], Range[]], boolean | void>>} */
|
378
379
|
callMemberChainOfCallMemberChain: new HookMap(
|
379
380
|
() =>
|
380
381
|
new SyncBailHook([
|
381
382
|
"expression",
|
382
383
|
"calleeMembers",
|
383
384
|
"innerCallExpression",
|
384
|
-
"members"
|
385
|
+
"members",
|
386
|
+
"memberRanges"
|
385
387
|
])
|
386
388
|
),
|
387
389
|
/** @type {SyncBailHook<[ChainExpression], boolean | void>} */
|
@@ -3274,7 +3276,8 @@ class JavascriptParser extends Parser {
|
|
3274
3276
|
expression,
|
3275
3277
|
exprInfo.getCalleeMembers(),
|
3276
3278
|
exprInfo.call,
|
3277
|
-
exprInfo.getMembers()
|
3279
|
+
exprInfo.getMembers(),
|
3280
|
+
exprInfo.getMemberRanges()
|
3278
3281
|
);
|
3279
3282
|
if (result === true) return;
|
3280
3283
|
}
|
@@ -3365,7 +3368,8 @@ class JavascriptParser extends Parser {
|
|
3365
3368
|
expression,
|
3366
3369
|
exprInfo.getCalleeMembers(),
|
3367
3370
|
exprInfo.call,
|
3368
|
-
exprInfo.getMembers()
|
3371
|
+
exprInfo.getMembers(),
|
3372
|
+
exprInfo.getMemberRanges()
|
3369
3373
|
);
|
3370
3374
|
if (result === true) return;
|
3371
3375
|
// Fast skip over the member chain as we already called memberChainOfCallMemberChain
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
/** @typedef {import("../Dependency")} Dependency */
|
9
|
+
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
10
|
+
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @summary Get the subset of ids and their corresponding range in an id chain that should be re-rendered by webpack.
|
14
|
+
* Only those in the chain that are actually referring to namespaces or imports should be re-rendered.
|
15
|
+
* Deeper member accessors on the imported object should not be re-rendered. If deeper member accessors are re-rendered,
|
16
|
+
* there is a potential loss of meaning with rendering a quoted accessor as an unquoted accessor, or vice versa,
|
17
|
+
* because minifiers treat quoted accessors differently. e.g. import { a } from "./module"; a["b"] vs a.b
|
18
|
+
* @param {string[]} untrimmedIds chained ids
|
19
|
+
* @param {Range} untrimmedRange range encompassing allIds
|
20
|
+
* @param {Range[]} ranges cumulative range of ids for each of allIds
|
21
|
+
* @param {ModuleGraph} moduleGraph moduleGraph
|
22
|
+
* @param {Dependency} dependency dependency
|
23
|
+
* @returns {{trimmedIds: string[], trimmedRange: Range}} computed trimmed ids and cumulative range of those ids
|
24
|
+
*/
|
25
|
+
exports.getTrimmedIdsAndRange = (
|
26
|
+
untrimmedIds,
|
27
|
+
untrimmedRange,
|
28
|
+
ranges,
|
29
|
+
moduleGraph,
|
30
|
+
dependency
|
31
|
+
) => {
|
32
|
+
let trimmedIds = trimIdsToThoseImported(
|
33
|
+
untrimmedIds,
|
34
|
+
moduleGraph,
|
35
|
+
dependency
|
36
|
+
);
|
37
|
+
let trimmedRange = untrimmedRange;
|
38
|
+
if (trimmedIds.length !== untrimmedIds.length) {
|
39
|
+
// The array returned from dep.idRanges is right-aligned with the array returned from dep.names.
|
40
|
+
// Meaning, the two arrays may not always have the same number of elements, but the last element of
|
41
|
+
// dep.idRanges corresponds to [the expression fragment to the left of] the last element of dep.names.
|
42
|
+
// Use this to find the correct replacement range based on the number of ids that were trimmed.
|
43
|
+
const idx =
|
44
|
+
ranges === undefined
|
45
|
+
? -1 /* trigger failure case below */
|
46
|
+
: ranges.length + (trimmedIds.length - untrimmedIds.length);
|
47
|
+
if (idx < 0 || idx >= ranges.length) {
|
48
|
+
// cspell:ignore minifiers
|
49
|
+
// Should not happen but we can't throw an error here because of backward compatibility with
|
50
|
+
// external plugins in wp5. Instead, we just disable trimming for now. This may break some minifiers.
|
51
|
+
trimmedIds = untrimmedIds;
|
52
|
+
// TODO webpack 6 remove the "trimmedIds = ids" above and uncomment the following line instead.
|
53
|
+
// throw new Error("Missing range starts data for id replacement trimming.");
|
54
|
+
} else {
|
55
|
+
trimmedRange = ranges[idx];
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
return { trimmedIds, trimmedRange };
|
60
|
+
};
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @summary Determine which IDs in the id chain are actually referring to namespaces or imports,
|
64
|
+
* and which are deeper member accessors on the imported object.
|
65
|
+
* @param {string[]} ids untrimmed ids
|
66
|
+
* @param {ModuleGraph} moduleGraph moduleGraph
|
67
|
+
* @param {Dependency} dependency dependency
|
68
|
+
* @returns {string[]} trimmed ids
|
69
|
+
*/
|
70
|
+
function trimIdsToThoseImported(ids, moduleGraph, dependency) {
|
71
|
+
let trimmedIds = [];
|
72
|
+
const exportsInfo = moduleGraph.getExportsInfo(
|
73
|
+
moduleGraph.getModule(dependency)
|
74
|
+
);
|
75
|
+
let currentExportsInfo = /** @type {ExportsInfo=} */ exportsInfo;
|
76
|
+
for (let i = 0; i < ids.length; i++) {
|
77
|
+
if (i === 0 && ids[i] === "default") {
|
78
|
+
continue; // ExportInfo for the next level under default is still at the root ExportsInfo, so don't advance currentExportsInfo
|
79
|
+
}
|
80
|
+
const exportInfo = currentExportsInfo.getExportInfo(ids[i]);
|
81
|
+
if (exportInfo.provided === false) {
|
82
|
+
// json imports have nested ExportInfo for elements that things that are not actually exported, so check .provided
|
83
|
+
trimmedIds = ids.slice(0, i);
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
const nestedInfo = exportInfo.getNestedExportsInfo();
|
87
|
+
if (!nestedInfo) {
|
88
|
+
// once all nested exports are traversed, the next item is the actual import so stop there
|
89
|
+
trimmedIds = ids.slice(0, i + 1);
|
90
|
+
break;
|
91
|
+
}
|
92
|
+
currentExportsInfo = nestedInfo;
|
93
|
+
}
|
94
|
+
// Never trim to nothing. This can happen for invalid imports (e.g. import { notThere } from "./module", or import { anything } from "./missingModule")
|
95
|
+
return trimmedIds.length ? trimmedIds : ids;
|
96
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "webpack",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.89.0",
|
4
4
|
"author": "Tobias Koppers @sokra",
|
5
5
|
"description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
6
6
|
"license": "MIT",
|
package/types.d.ts
CHANGED
@@ -5521,13 +5521,19 @@ declare class JavascriptParser extends Parser {
|
|
5521
5521
|
>;
|
5522
5522
|
memberChainOfCallMemberChain: HookMap<
|
5523
5523
|
SyncBailHook<
|
5524
|
-
[Expression, string[], CallExpression, string[]],
|
5524
|
+
[Expression, string[], CallExpression, string[], [number, number][]],
|
5525
5525
|
boolean | void
|
5526
5526
|
>
|
5527
5527
|
>;
|
5528
5528
|
callMemberChainOfCallMemberChain: HookMap<
|
5529
5529
|
SyncBailHook<
|
5530
|
-
[
|
5530
|
+
[
|
5531
|
+
CallExpression,
|
5532
|
+
string[],
|
5533
|
+
CallExpression,
|
5534
|
+
string[],
|
5535
|
+
[number, number][]
|
5536
|
+
],
|
5531
5537
|
boolean | void
|
5532
5538
|
>
|
5533
5539
|
>;
|