From f2a6fdb36044c47e0b18f7caa0a126eced16a310 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 21 Apr 2026 05:06:07 +0000 Subject: [PATCH 1/6] add failing test: paths mapping loses to sibling project file --- test/transpile/module-resolution.spec.ts | 12 ++++++++++++ .../paths-vs-project-file/other/alias.ts | 1 + .../paths-vs-project-file/program/alias.ts | 1 + .../paths-vs-project-file/program/main.ts | 3 +++ .../paths-vs-project-file/program/tsconfig.json | 9 +++++++++ 5 files changed, 26 insertions(+) create mode 100644 test/transpile/module-resolution/paths-vs-project-file/other/alias.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/alias.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/main.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index ff29ac9b5..36defb02a 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -711,6 +711,18 @@ test("paths without baseUrl is error", () => { util.testFunction``.setOptions({ paths: {} }).expectToHaveDiagnostics([pathsWithoutBaseUrl.code]); }); +test("paths mapping wins over sibling project file (TS resolution order)", () => { + const baseProjectPath = path.resolve(__dirname, "module-resolution", "paths-vs-project-file"); + const projectPath = path.join(baseProjectPath, "program"); + const projectTsConfig = path.join(projectPath, "tsconfig.json"); + const mainFile = path.join(projectPath, "main.ts"); + + util.testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ value: "paths-mapped" }); +}); + test("module resolution using plugin", () => { const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); diff --git a/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts b/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts new file mode 100644 index 000000000..b09331910 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts @@ -0,0 +1 @@ +export const value = "paths-mapped"; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts b/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts new file mode 100644 index 000000000..565154b68 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts @@ -0,0 +1 @@ +export const value = "project-file"; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/main.ts b/test/transpile/module-resolution/paths-vs-project-file/program/main.ts new file mode 100644 index 000000000..7b4bc6587 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/main.ts @@ -0,0 +1,3 @@ +import { value } from "alias"; + +export { value }; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json new file mode 100644 index 000000000..26c1a151f --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "rootDir": "..", + "outDir": "dist", + "paths": { + "alias": ["../other/alias"] + } + } +} From 82571b03970ccc39835605e6cb21d2b1f0cfb67d Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 21 Apr 2026 08:58:14 +0000 Subject: [PATCH 2/6] add temporary TS <6.0 support --- .../paths-vs-project-file/program/tsconfig.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json index 26c1a151f..58a19f2ad 100644 --- a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -4,6 +4,12 @@ "outDir": "dist", "paths": { "alias": ["../other/alias"] - } + }, + // TODO: Remove after TS 6 migration + // `baseUrl` is deprecated in TS 6 and planned to be completely + // removed in TS 7 + "baseUrl": ".", + "ignoreDeprecations": "6.0" + // End of TODO block } } From be0cab78bc61b568465876eec0e44ed01a9ab334 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 21 Apr 2026 09:06:40 +0000 Subject: [PATCH 3/6] resolve paths mappings before sibling project files to match ts order --- src/transpilation/resolve.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index bd16773e9..6af84d6b5 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -210,13 +210,9 @@ class ResolutionContext { if (resolvedNodeModulesFile) return resolvedNodeModulesFile; } - // Check if file is a file in the project - const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); - const fileFromPath = this.getFileFromPath(resolvedPath); - if (fileFromPath) return fileFromPath; - - if (this.options.paths && this.options.baseUrl) { - // If no file found yet and paths are present, try to find project file via paths mappings + // Bare specifiers: check paths mappings first, matching TypeScript's resolution order. + // TS never applies paths to relative imports, so skip for those. + if (!ts.isExternalModuleNameRelative(dependencyPath) && this.options.paths && this.options.baseUrl) { const fileFromPaths = this.tryGetModuleNameFromPaths( dependencyPath, this.options.paths, @@ -225,6 +221,11 @@ class ResolutionContext { if (fileFromPaths) return fileFromPaths; } + // Check if file is a file in the project + const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); + const fileFromPath = this.getFileFromPath(resolvedPath); + if (fileFromPath) return fileFromPath; + // Not a TS file in our project sources, use resolver to check if we can find dependency try { const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); From 4a69a053c26f65e1b6335ede7b4e68dcd9a2f4a3 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 21 Apr 2026 09:07:01 +0000 Subject: [PATCH 4/6] don't need ignoreDeprecations --- .../paths-vs-project-file/program/tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json index 58a19f2ad..89dfb3dc0 100644 --- a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -8,8 +8,7 @@ // TODO: Remove after TS 6 migration // `baseUrl` is deprecated in TS 6 and planned to be completely // removed in TS 7 - "baseUrl": ".", - "ignoreDeprecations": "6.0" + "baseUrl": "." // End of TODO block } } From e0f6984dd754387db5a5efb9c4ea3f0b17067fb8 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 21 Apr 2026 09:14:56 +0000 Subject: [PATCH 5/6] remove redundant end-of-todo-block comment --- .../paths-vs-project-file/program/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json index 89dfb3dc0..fc825b0c3 100644 --- a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -9,6 +9,5 @@ // `baseUrl` is deprecated in TS 6 and planned to be completely // removed in TS 7 "baseUrl": "." - // End of TODO block } } From fbe1d584e20117bbe2c0e958c68d3e77a48c4bb7 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Wed, 22 Apr 2026 01:59:08 +0000 Subject: [PATCH 6/6] drop baseUrl from paths-vs-project-file test fixture --- .../paths-vs-project-file/program/tsconfig.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json index fc825b0c3..26c1a151f 100644 --- a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -4,10 +4,6 @@ "outDir": "dist", "paths": { "alias": ["../other/alias"] - }, - // TODO: Remove after TS 6 migration - // `baseUrl` is deprecated in TS 6 and planned to be completely - // removed in TS 7 - "baseUrl": "." + } } }