diff --git a/lib/runner/resolveFilePath.ts b/lib/runner/resolveFilePath.ts index b381e617..e47dc5d1 100644 --- a/lib/runner/resolveFilePath.ts +++ b/lib/runner/resolveFilePath.ts @@ -1,7 +1,10 @@ import { normalizeFilePath } from "./normalizeFsMap" -import { dirname } from "lib/utils/dirname" -import { resolveWithTsconfigPaths, type TsConfig } from "./tsconfigPaths" import { resolveRelativePath } from "lib/utils/resolveRelativePath" +import { + resolveWithTsconfigPaths, + type TsConfig, + resolveWithBaseUrl, +} from "./tsconfigPaths" export const resolveFilePath = ( unknownFilePath: string, @@ -48,13 +51,21 @@ export const resolveFilePath = ( const tsConfig = opts.tsConfig ?? null if (!unknownFilePath.startsWith("./") && !unknownFilePath.startsWith("../")) { - const viaTsconfig = resolveWithTsconfigPaths({ + const resolvedPathFromPaths = resolveWithTsconfigPaths({ importPath: unknownFilePath, normalizedFilePathMap, extensions: extension, tsConfig, }) - if (viaTsconfig) return viaTsconfig + if (resolvedPathFromPaths) return resolvedPathFromPaths + + const resolvedPathFromBaseUrl = resolveWithBaseUrl({ + importPath: unknownFilePath, + normalizedFilePathMap, + extensions: extension, + tsConfig, + }) + if (resolvedPathFromBaseUrl) return resolvedPathFromBaseUrl } // Check if it's an absolute import diff --git a/lib/runner/tsconfigPaths.ts b/lib/runner/tsconfigPaths.ts index 3d80b4a2..5dd22e7b 100644 --- a/lib/runner/tsconfigPaths.ts +++ b/lib/runner/tsconfigPaths.ts @@ -90,6 +90,42 @@ export function resolveWithTsconfigPaths(opts: { } } + const resolvedPathFromBaseUrl = resolveWithBaseUrl({ + importPath, + normalizedFilePathMap, + extensions, + tsConfig, + }) + + if (resolvedPathFromBaseUrl) return resolvedPathFromBaseUrl + + return null +} + +export function resolveWithBaseUrl(opts: { + importPath: string + normalizedFilePathMap: Map + extensions: string[] + tsConfig: TsConfig | null +}): string | null { + const { importPath, normalizedFilePathMap, extensions, tsConfig } = opts + const baseUrl = tsConfig?.compilerOptions?.baseUrl + if (!baseUrl) return null + + const filePathToResolve = `${baseUrl}/${importPath}` + const normalizedFilePath = normalizeFilePath(filePathToResolve) + + if (normalizedFilePathMap.has(normalizedFilePath)) { + return normalizedFilePathMap.get(normalizedFilePath)! + } + + for (const ext of extensions) { + const withExt = `${normalizedFilePath}.${ext}` + if (normalizedFilePathMap.has(withExt)) { + return normalizedFilePathMap.get(withExt)! + } + } + return null } diff --git a/tests/features/tsconfig-paths-resolution.test.tsx b/tests/features/tsconfig-paths-resolution.test.tsx index 725dc89b..a1b4a71b 100644 --- a/tests/features/tsconfig-paths-resolution.test.tsx +++ b/tests/features/tsconfig-paths-resolution.test.tsx @@ -63,3 +63,36 @@ test("throws error when tsconfig path alias cannot be resolved (instead of tryin 'Import "@utils/missing" matches a tsconfig path alias but could not be resolved to an existing file', ) }) + +test("resolves imports using tsconfig baseUrl", async () => { + const circuitJson = await runTscircuitCode( + { + "tsconfig.json": JSON.stringify({ + compilerOptions: { + baseUrl: "src", + }, + }), + "src/utils/values.ts": ` + export const resistorName = "RbaseUrl" + export const resistance = "2k" + `, + "src/component.tsx": ` + import { resistorName, resistance } from "utils/values" + export default () => () + `, + "user.tsx": ` + import Comp from "component" + export default () => () + `, + }, + { + mainComponentPath: "user", + }, + ) + + const resistor = circuitJson.find( + (el) => el.type === "source_component" && el.name === "RbaseUrl", + ) as any + expect(resistor).toBeDefined() + expect(resistor.resistance).toBe(2000) +})