feat(javascript): resolve exact package import aliases (#1862)

* feat(javascript): resolve exact package import aliases

Resolve exact #alias specifiers against the importer's enclosing
package.json imports map using the shared condition, array, and null
target selection. Nested packages keep their own maps; missing keys,
explicit nulls, and out-of-scope aliases report a precise reason.
Wildcard, recursive, and external-package import targets remain
unresolved.

* fix(javascript): keep nested import aliases in CLI graphs

Bound nested #alias requires produce application-graph require edges
from the enclosing package. Node reports MODULE_NOT_FOUND when a nested
package.json has no imports field, without inheriting the ancestor map.

* fix(javascript): resolve literal package import keys before path admission

* fix(javascript): preserve import keys and invalid-target fallback

* fix(javascript): preserve unmatched package target arrays

* fix(javascript): retain package target refusal evidence

* test(browser): match real verifier startup budget

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
This commit is contained in:
Matt Van Hornandmorluto authored and GitHub committed 2026-10-12 01:17:58 +08:00
1 parent e8491e023a
commit d28b41ea4e
10 files changed
+1838 -83

No files matched your search

@@ -868,6 +868,365 @@ describe("package exports exact targets", () => {
});
});
describe("package import alias resolution", () => {
it.each(["import", "require"] as const)(
"resolves an exact #%s alias from the enclosing package imports map",
(moduleKind) => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./config.cjs" },
}),
"main.js": "",
"config.cjs": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind,
files,
}),
).toMatchObject({
resolution_status: "resolved",
resolved_path: "config.cjs",
declared_path: "#config",
});
},
);
it("resolves an alias from a nested file through the enclosing package root", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./config.cjs" },
}),
"src/main.js": "",
"config.cjs": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "src/main.js",
context: "module-specifier",
moduleKind: "require",
files,
}),
).toMatchObject({
resolution_status: "resolved",
resolved_path: "config.cjs",
});
});
it("uses a nested package imports map rather than the application root", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./root.cjs" },
}),
"root.cjs": "",
"node_modules/fixture/package.json": JSON.stringify({
imports: { "#config": "./local.cjs" },
}),
"node_modules/fixture/index.js": "",
"node_modules/fixture/local.cjs": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "node_modules/fixture/index.js",
context: "module-specifier",
moduleKind: "require",
files,
}),
).toMatchObject({
resolution_status: "resolved",
resolved_path: "node_modules/fixture/local.cjs",
});
});
it("does not inherit an ancestor imports map across a nested package.json", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./root.cjs" },
}),
"root.cjs": "",
"node_modules/fixture/package.json": "{}",
"node_modules/fixture/index.js": "",
});
const outcome = resolve({
declaredPath: "#config",
sourcePath: "node_modules/fixture/index.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(outcome).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toContain(
"node_modules/fixture/package.json",
);
expect(outcome.limitations.join(" ")).not.toContain("root.cjs");
});
it("does not apply a nested package map to the application root importer", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./root.cjs" },
}),
"main.js": "",
"root.cjs": "",
"node_modules/fixture/package.json": JSON.stringify({
imports: { "#config": "./local.cjs" },
}),
"node_modules/fixture/local.cjs": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
}),
).toMatchObject({
resolution_status: "resolved",
resolved_path: "root.cjs",
});
});
});
describe("package import alias target selection", () => {
it("selects import and require conditions from an imports target", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: {
"#config": {
import: "./config.mjs",
require: "./config.cjs",
default: "./fallback.js",
},
},
}),
"main.js": "",
"config.mjs": "",
"config.cjs": "",
"fallback.js": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "import",
files,
}).resolved_path,
).toBe("config.mjs");
expect(
resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
}).resolved_path,
).toBe("config.cjs");
});
it("resolves array import targets at their first string entry", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": [{ import: "./missing.mjs" }, "./config.cjs"] },
}),
"main.js": "",
"config.cjs": "",
});
expect(
resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
}),
).toMatchObject({
resolution_status: "resolved",
resolved_path: "config.cjs",
});
});
it("does not add an extension or index to a selected import target", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./config" },
}),
"main.js": "",
"config.cjs": "",
"config/index.js": "",
});
const outcome = resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(outcome).toMatchObject({
resolution_status: "not-found",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toContain(
"import targets are exact files",
);
});
});
describe("package import alias refusals", () => {
it("reports a missing exact alias without looking in another package", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./config.cjs" },
}),
"main.js": "",
"config.cjs": "",
});
const outcome = resolve({
declaredPath: "#other",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(outcome).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toContain("#other");
expect(outcome.limitations.join(" ")).toContain("#config");
});
it("reports an explicit null import target as blocked", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": null },
}),
"main.js": "",
"config.cjs": "",
});
const outcome = resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(outcome).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toContain("explicit null");
});
it("leaves wildcard import aliases unresolved", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#internal/*": "./src/*.js" },
}),
"main.js": "",
"src/util.js": "",
});
const outcome = resolve({
declaredPath: "#internal/util",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "import",
files,
});
expect(outcome).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toMatch(/wildcard/i);
});
it("leaves recursive and external-package import targets unresolved", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#loop": "#config", "#dep": "fixture" },
}),
"main.js": "",
"node_modules/fixture/index.js": "",
});
const recursive = resolve({
declaredPath: "#loop",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
const external = resolve({
declaredPath: "#dep",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(recursive).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(recursive.limitations.join(" ")).toMatch(/recursive/i);
expect(external).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(external.limitations.join(" ")).toMatch(/external-package/i);
});
it("rejects reserved hash specifiers", () => {
const files = aliasFiles({
"package.json": JSON.stringify({
imports: { "#config": "./config.cjs" },
}),
"main.js": "",
"config.cjs": "",
});
expect(
resolve({
declaredPath: "#",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "import",
files,
}),
).toMatchObject({ resolution_status: "rejected", resolved_path: null });
});
it("does not use a foreign-container enclosing package.json", () => {
const files = fileMap([
file(
"package.json",
"other",
JSON.stringify({ imports: { "#config": "./config.cjs" } }),
),
file("main.js", "root"),
file("config.cjs", "root"),
]);
const outcome = resolve({
declaredPath: "#config",
sourcePath: "main.js",
context: "module-specifier",
moduleKind: "require",
files,
});
expect(outcome).toMatchObject({
resolution_status: "external",
resolved_path: null,
});
expect(outcome.limitations.join(" ")).toContain("package scopes");
});
});
describe("directory package entrypoint precedence", () => {
it.each([
["require", '{"main":"actual.cjs"}', "actual.cjs"],
@@ -1211,6 +1570,15 @@ const file = (
: { included: true, value: text },
});
const aliasFiles = (
entries: Readonly<Record<string, string | null>>,
): ReturnType<typeof fileMap> =>
fileMap(
Object.entries(entries).map(([path, text]) =>
file(path, "root", text ?? ""),
),
);
describe("exact HTML resource resolution", () => {
it.each([
["extension", ["app.js"]],