Skip to content

Commit faa178f

Browse files
fix(TsconfigPathsPlugin): give references priority over main paths (#552)
1 parent e82275d commit faa178f

6 files changed

Lines changed: 117 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const source = "main";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const source = "ref";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"paths": {
5+
"@lib/*": ["./ref-lib/*"]
6+
},
7+
"composite": true,
8+
"outDir": "./dist"
9+
}
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"paths": {
5+
"@lib/*": ["./main-lib/*"]
6+
}
7+
},
8+
"references": [{ "path": "./ref" }]
9+
}

test/tsconfig-paths.test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,101 @@ describe("TsconfigPathsPlugin", () => {
10031003
);
10041004
});
10051005
});
1006+
1007+
describe("paths are scoped to the containing tsconfig (tsc-aligned)", () => {
1008+
// Fixture layout:
1009+
// references-priority/tsconfig.json -> "@lib/*": ["./main-lib/*"], references ./ref
1010+
// references-priority/main-lib/foo.ts (source = "main")
1011+
// references-priority/ref/tsconfig.json -> "@lib/*": ["./ref-lib/*"]
1012+
// references-priority/ref/ref-lib/foo.ts (source = "ref")
1013+
//
1014+
// `tsc` resolves `paths` using the tsconfig that owns the importing
1015+
// file, not by merging across a `references` edge, so each context
1016+
// must see its own target even though the alias name collides.
1017+
const referencesPriorityDir = path.resolve(
1018+
__dirname,
1019+
"fixtures",
1020+
"tsconfig-paths",
1021+
"references-priority",
1022+
);
1023+
const refDir = path.join(referencesPriorityDir, "ref");
1024+
1025+
it("resolves @lib/foo from the main context to main's target", (done) => {
1026+
const resolver = ResolverFactory.createResolver({
1027+
fileSystem,
1028+
extensions: [".ts", ".tsx"],
1029+
mainFields: ["browser", "main"],
1030+
mainFiles: ["index"],
1031+
tsconfig: {
1032+
configFile: path.join(referencesPriorityDir, "tsconfig.json"),
1033+
references: "auto",
1034+
},
1035+
});
1036+
1037+
resolver.resolve(
1038+
{},
1039+
referencesPriorityDir,
1040+
"@lib/foo",
1041+
{},
1042+
(err, result) => {
1043+
if (err) return done(err);
1044+
if (!result) return done(new Error("No result"));
1045+
expect(result).toEqual(
1046+
path.join(referencesPriorityDir, "main-lib", "foo.ts"),
1047+
);
1048+
done();
1049+
},
1050+
);
1051+
});
1052+
1053+
it("resolves @lib/foo from the reference context to the reference's target", (done) => {
1054+
const resolver = ResolverFactory.createResolver({
1055+
fileSystem,
1056+
extensions: [".ts", ".tsx"],
1057+
mainFields: ["browser", "main"],
1058+
mainFiles: ["index"],
1059+
tsconfig: {
1060+
configFile: path.join(referencesPriorityDir, "tsconfig.json"),
1061+
references: "auto",
1062+
},
1063+
});
1064+
1065+
resolver.resolve({}, refDir, "@lib/foo", {}, (err, result) => {
1066+
if (err) return done(err);
1067+
if (!result) return done(new Error("No result"));
1068+
expect(result).toEqual(path.join(refDir, "ref-lib", "foo.ts"));
1069+
done();
1070+
});
1071+
});
1072+
1073+
it("reference paths do not leak into a sibling/unrelated main lookup", (done) => {
1074+
// When references are loaded but the request is made from the
1075+
// main context, the reference's alias target must not win over
1076+
// the main's target — even if the reference's target also exists.
1077+
const resolver = ResolverFactory.createResolver({
1078+
fileSystem,
1079+
extensions: [".ts", ".tsx"],
1080+
mainFields: ["browser", "main"],
1081+
mainFiles: ["index"],
1082+
tsconfig: {
1083+
configFile: path.join(referencesPriorityDir, "tsconfig.json"),
1084+
references: "auto",
1085+
},
1086+
});
1087+
1088+
resolver.resolve(
1089+
{},
1090+
referencesPriorityDir,
1091+
"@lib/foo",
1092+
{},
1093+
(err, result) => {
1094+
if (err) return done(err);
1095+
expect(result).not.toEqual(path.join(refDir, "ref-lib", "foo.ts"));
1096+
done();
1097+
},
1098+
);
1099+
});
1100+
});
10061101
});
10071102

10081103
describe("bug: baseUrl from deep extends chain (non-sibling directories)", () => {

0 commit comments

Comments
 (0)