Skip to content

Commit 7e7af04

Browse files
authored
fix: incorrect identifier of import binding for module externals (#20107)
1 parent 44136c1 commit 7e7af04

17 files changed

Lines changed: 113 additions & 66 deletions

File tree

lib/ConcatenationScope.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,6 @@ class ConcatenationScope {
112112
this._currentModule.namespaceExportSymbol = symbol;
113113
}
114114

115-
/**
116-
* @param {string} symbol identifier of the export in source code
117-
* @returns {boolean} registered success
118-
*/
119-
registerUsedName(symbol) {
120-
if (this.usedNames.has(symbol)) {
121-
return false;
122-
}
123-
this.usedNames.add(symbol);
124-
return true;
125-
}
126-
127115
/**
128116
* @param {Module} module the referenced module
129117
* @param {Partial<ModuleReferenceOptions>} options options
@@ -189,7 +177,4 @@ class ConcatenationScope {
189177
ConcatenationScope.DEFAULT_EXPORT = DEFAULT_EXPORT;
190178
ConcatenationScope.NAMESPACE_OBJECT_EXPORT = NAMESPACE_OBJECT_EXPORT;
191179

192-
/** @type {WeakMap<Chunk, Set<string>>} */
193-
ConcatenationScope.chunkUsedNames = new WeakMap();
194-
195180
module.exports = ConcatenationScope;

lib/ExternalModule.js

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -474,22 +474,6 @@ const getSourceForModuleExternal = (
474474
runtimeTemplate.outputOptions.hashFunction
475475
);
476476
const normalizedImported = initFragment.getImported();
477-
const specifiers =
478-
normalizedImported === true
479-
? undefined
480-
: /** @type {[string, string][]} */ (
481-
normalizedImported.map(([name, rawFinalName]) => {
482-
let finalName = rawFinalName;
483-
let counter = 0;
484-
485-
if (concatenationScope) {
486-
while (!concatenationScope.registerUsedName(finalName)) {
487-
finalName = `${finalName}_${counter++}`;
488-
}
489-
}
490-
return [name, finalName];
491-
})
492-
);
493477

494478
const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
495479
moduleAndSpecifiers,
@@ -519,7 +503,7 @@ const getSourceForModuleExternal = (
519503
"x"
520504
)}`
521505
: undefined,
522-
specifiers,
506+
specifiers: normalizedImported === true ? undefined : normalizedImported,
523507
runtimeRequirements: moduleRemapping
524508
? RUNTIME_REQUIREMENTS_FOR_MODULE
525509
: undefined,

lib/optimize/ConcatenatedModule.js

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,6 @@ const compareNumbers = (a, b) => {
225225
const bySourceOrder = createComparator("sourceOrder", compareNumbers);
226226
const byRangeStart = createComparator("rangeStart", compareNumbers);
227227

228-
const INITIAL_USED_NAMES = new Set(RESERVED_NAMES);
229-
230228
/**
231229
* @param {Iterable<string>} iterable iterable object
232230
* @returns {string} joined iterable object
@@ -1277,18 +1275,8 @@ class ConcatenatedModule extends Module {
12771275
/** @type {NeededNamespaceObjects} */
12781276
const neededNamespaceObjects = new Set();
12791277

1280-
// Default disallowed names
1281-
const allUsedNames = new Set(INITIAL_USED_NAMES);
1282-
const chunks = chunkGraph.getModuleChunks(this);
1283-
1284-
// Add names already used in the current chunk scope
1285-
for (const chunk of chunks) {
1286-
if (ConcatenationScope.chunkUsedNames.has(chunk)) {
1287-
for (const name of ConcatenationScope.chunkUsedNames.get(chunk) || []) {
1288-
allUsedNames.add(name);
1289-
}
1290-
}
1291-
}
1278+
// List of all used names to avoid conflicts
1279+
const allUsedNames = new Set(RESERVED_NAMES);
12921280

12931281
// Generate source code and analyse scopes
12941282
// Prepare a ReplaceSource for the final source
@@ -1307,23 +1295,6 @@ class ConcatenatedModule extends Module {
13071295
);
13081296
}
13091297

1310-
// Record the names registered by the current ConcatenatedModule into the chunk scope
1311-
if (INITIAL_USED_NAMES.size !== allUsedNames.size) {
1312-
for (const name of allUsedNames) {
1313-
if (INITIAL_USED_NAMES.has(name)) continue;
1314-
1315-
for (const chunk of chunks) {
1316-
if (!ConcatenationScope.chunkUsedNames.has(chunk)) {
1317-
ConcatenationScope.chunkUsedNames.set(chunk, new Set([name]));
1318-
} else {
1319-
/** @type {Set<string>} */ (
1320-
ConcatenationScope.chunkUsedNames.get(chunk)
1321-
).add(name);
1322-
}
1323-
}
1324-
}
1325-
}
1326-
13271298
// Updated Top level declarations are created by renaming
13281299
/** @type {TopLevelDeclarations} */
13291300
const topLevelDeclarations = new Set();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("./foo1").foo;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { a as concat2_a, b as concat2_b, c as concat2_c } from "./concat2";
2+
3+
export const a = "concat1~" + concat2_a;
4+
export const b = "concat1~" + concat2_b;
5+
export const c = "concat1~" + concat2_c;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { a as external_a, b as external_b, c as external_c } from "external";
2+
3+
export const a = "concat2~" + external_a;
4+
export const b = "concat2~" + external_b;
5+
export const c = "concat2~" + external_c;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This concat module has size `4`
2+
import { a, b, c } from "./concat1";
3+
4+
// Create one shared concat module that exist in multiple chunks
5+
import cjs from "./cjs-concat";
6+
7+
it("should generate correct specifier pointed to import binding / 1", function () {
8+
expect(a).toBe("concat1~concat2~external-a");
9+
expect(b).toBe("concat1~concat2~external-b");
10+
expect(c).toBe("concat1~concat2~external-c");
11+
expect(cjs).toBe("foo1~foo2~foo3~foo4");
12+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This concat module has size `3`
2+
import { a, b, c } from "./concat2";
3+
4+
// Create one shared concat module that exist in multiple chunks
5+
import cjs from "./cjs-concat";
6+
7+
it("should generate correct specifier pointed to import binding / 2", function () {
8+
expect(a).toBe("concat2~external-a");
9+
expect(b).toBe("concat2~external-b");
10+
expect(c).toBe("concat2~external-c");
11+
expect(cjs).toBe("foo1~foo2~foo3~foo4");
12+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const a = "external-a"
2+
export const b = "external-b"
3+
export const c = "external-c"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// This concat module has size `4`
2+
import foo2 from "./foo2";
3+
4+
export const foo = "foo1~" + foo2;

0 commit comments

Comments
 (0)