mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-04 08:04:37 +08:00
Ship a joined island data path when another directory has its name
A module that names fallback/payload.txt through join(here, "fallback", "payload.txt") also names "payload.txt" alone. That name was checked against the first file of that name the directory walk found, so a payload.txt in another subdirectory made the build fail with SC8006 even though the joined path ships. A name whose file a named path of the same module ships is no longer reported.
This commit is contained in:
@@ -334,6 +334,21 @@ describe("the collected module tree", () => {
|
||||
expect(paths.filter((path) => !path.endsWith(".cjs"))).toEqual(["assets/config.json"]);
|
||||
});
|
||||
|
||||
test("a joined data path ships even when another directory has a file of that name", () => {
|
||||
const root = project({
|
||||
"src/main.ts": "",
|
||||
"src/loader.cjs":
|
||||
'const { join } = require("node:path");\nrequire("node:fs").readFileSync(join(__dirname, "fallback", "payload.txt"));\n',
|
||||
"src/a-other/payload.txt": "not named by the module\n",
|
||||
"src/fallback/payload.txt": "shipped\n",
|
||||
});
|
||||
const collector = new NodeIslandModuleCollector();
|
||||
expect(collector.add(join(root, "src/main.ts"), "./loader.cjs")).toBeNull();
|
||||
const paths = collector.tree()!.files.map((file) => file.path);
|
||||
expect(paths).toContain("fallback/payload.txt");
|
||||
expect(paths).not.toContain("a-other/payload.txt");
|
||||
});
|
||||
|
||||
test("a named file that is only elsewhere in the module's directory is a build error", () => {
|
||||
const root = project({
|
||||
"src/main.ts": "",
|
||||
|
||||
@@ -368,6 +368,8 @@ export class NodeIslandModuleCollector {
|
||||
return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
|
||||
};
|
||||
const unresolved: { name: string; at: number }[] = [];
|
||||
/** The names of the files this module's named paths ship. */
|
||||
const shippedNames = new Set<string>();
|
||||
for (const [name, at] of namedDataPaths(text)) {
|
||||
if (isAbsolute(name) || name.includes("\0")) continue;
|
||||
const path = resolve(root, name);
|
||||
@@ -382,6 +384,7 @@ export class NodeIslandModuleCollector {
|
||||
if (target === null || !inside(target)) continue;
|
||||
// A link inside the directory stays a link in the tree (placed).
|
||||
this.files.add(this.placed(path));
|
||||
shippedNames.add(basename(path));
|
||||
}
|
||||
if (unresolved.length === 0) return null;
|
||||
// The files of the module's directory by name, links leading outside it
|
||||
@@ -405,9 +408,11 @@ export class NodeIslandModuleCollector {
|
||||
};
|
||||
walk(root);
|
||||
for (const { name, at } of unresolved) {
|
||||
// A name of a file another named path ships (`"payload.txt"` beside
|
||||
// `join(here, "fallback", "payload.txt")`) is not missing, wherever
|
||||
// other files of that name are.
|
||||
if (shippedNames.has(basename(name))) continue;
|
||||
const found = byName.get(basename(name));
|
||||
// A file another named path ships (`"payload.txt"` beside
|
||||
// `join(here, "fallback", "payload.txt")`) is not missing.
|
||||
if (found === undefined || this.files.has(trackedRealpath(found) ?? found)) continue;
|
||||
const line = text.slice(0, at).split("\n").length;
|
||||
const there = portable(relative(root, found));
|
||||
|
||||
Reference in New Issue
Block a user