fix(javascript): keep Vite dependency slots after a spread unknown (#4023)
The __vite__mapDeps table indexer mapped a spread element to one unknown slot, so every later entry kept a definite index even though the spread can add any number of elements. A call such as __vite__mapDeps([0, 2]) over ["./first.js", ...["./middle-a.js", "./middle-b.js"], "./last.js"] then resolved index 2 to last.js instead of middle-b.js. Keep only the entries before the first spread; indexes from the spread onward stay unknown.
This commit is contained in:
2 files changed
+23
-1
No files matched your search
@@ -398,7 +398,14 @@ export const indexVitePreloadDependencyTable = (
|
||||
if (tables.length !== 1) return [];
|
||||
const table = tables[0];
|
||||
if (table === undefined) return [];
|
||||
const dependencies = table.elements.map((element) =>
|
||||
// A spread contributes an unknown number of entries, so every later slot
|
||||
// has an unknown index; leave those out instead of shifting them.
|
||||
const spread = table.elements.findIndex((element) =>
|
||||
t.isSpreadElement(element),
|
||||
);
|
||||
const dependencies = (
|
||||
spread === -1 ? table.elements : table.elements.slice(0, spread)
|
||||
).map((element) =>
|
||||
element === null || t.isSpreadElement(element)
|
||||
? undefined
|
||||
: stringValue(element),
|
||||
|
||||
@@ -83,4 +83,19 @@ describe("Vite preload dependency recovery", () => {
|
||||
.map(({ specifier }) => specifier),
|
||||
).toEqual(["./original.js"]);
|
||||
});
|
||||
|
||||
it("keeps table slots from a spread onward unknown", () => {
|
||||
const analysis = analyzeJavaScriptStaticSource(`
|
||||
const __vite__mapDeps = (indexes, map = __vite__mapDeps, dependencies =
|
||||
(map.f || (map.f = ["./first.js", ...["./middle-a.js", "./middle-b.js"], "./last.js"]))) =>
|
||||
indexes.map((index) => dependencies[index]);
|
||||
__vite__mapDeps([0, 2]);
|
||||
`);
|
||||
|
||||
expect(
|
||||
analysis.references
|
||||
.filter(({ kind }) => kind === "dynamic-import")
|
||||
.map(({ specifier }) => specifier),
|
||||
).toEqual(["./first.js", null]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user