diff --git a/index.ts b/index.ts index 6ea0890..89f3f44 100644 --- a/index.ts +++ b/index.ts @@ -1,21 +1,15 @@ -import { join } from 'path'; +import path from 'path'; import { Plugin } from 'rollup'; -import { - CompilerOptions, - findConfigFile, - nodeModuleNameResolver, - parseConfigFileTextToJson, - sys, -} from 'typescript'; +import * as ts from 'typescript'; export const typescriptPaths = ({ absolute = true, nonRelative = false, preserveExtensions = false, - tsConfigPath = findConfigFile('./', sys.fileExists), + tsConfigPath = ts.findConfigFile('./', ts.sys.fileExists), transform, }: Options = {}): Plugin => { - const { compilerOptions, outDir } = getTsConfig(tsConfigPath); + const compilerOptions = getTsConfig(tsConfigPath); return { name: 'resolve-typescript-paths', @@ -46,11 +40,11 @@ export const typescriptPaths = ({ return null; // never resolve relative modules, only non-relative } - const { resolvedModule } = nodeModuleNameResolver( + const { resolvedModule } = ts.nodeModuleNameResolver( importee, importer, compilerOptions, - sys, + ts.sys, ); if (!resolvedModule) { @@ -63,15 +57,16 @@ export const typescriptPaths = ({ return null; } - const targetFileName = join( - outDir, + // TODO: Do we need outDir as "resolvedFileName" is already correct absolute path + const targetFileName = path.join( + compilerOptions.outDir, preserveExtensions ? resolvedFileName : resolvedFileName.replace(/\.tsx?$/i, '.js'), ); const resolved = absolute - ? sys.resolvePath(targetFileName) + ? ts.sys.resolvePath(targetFileName) : targetFileName; return transform ? transform(resolved) : resolved; @@ -80,21 +75,45 @@ export const typescriptPaths = ({ }; const getTsConfig = (configPath?: string): TsConfig => { - const defaults: TsConfig = { compilerOptions: {}, outDir: '.' }; - - if (!configPath) { + const defaults: TsConfig = { outDir: '.' }; + if (typeof configPath !== 'string') { return defaults; } - const configJson = sys.readFile(configPath); + // Define a host object that implements ParseConfigFileHost. + // The host provides file system operations and error handling for parsing the configuration file. + const host: ts.ParseConfigFileHost = { + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + readDirectory: ts.sys.readDirectory, + useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames, + getCurrentDirectory: ts.sys.getCurrentDirectory, + onUnRecoverableConfigFileDiagnostic: (diagnostic) => { + console.error( + 'Unrecoverable error in config file:', + diagnostic.messageText, + ); + process.exit(1); + }, + }; - if (!configJson) { - return defaults; + // Read in tsconfig.json + const parsedCommandLine = ts.getParsedCommandLineOfConfigFile( + configPath, + {}, + host, + ); + + // Access the parsed tsconfig.json file options + let resolvedConfig = {}; + if (parsedCommandLine != null) { + resolvedConfig = parsedCommandLine.options; + } else { + console.error('Failed to parse TypeScript configuration file:', configPath); + process.exit(1); } - const { config } = parseConfigFileTextToJson(configPath, configJson); - - return { ...defaults, ...config }; + return { ...defaults, ...resolvedConfig }; }; export interface Options { @@ -131,10 +150,9 @@ export interface Options { transform?(path: string): string; } -interface TsConfig { - compilerOptions: CompilerOptions; +type TsConfig = { outDir: string; -} +} & Omit; /** * For backwards compatibility. diff --git a/package.json b/package.json index be3282d..c706a1c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "scripts": { "test": "npm run prepare && node test", "preversion": "npm test", - "prepare": "rm -rf dist && tsc" + "prepare": "shx rm -rf dist && tsc", + "format": "prettier --write \"**/*.{js,ts,tsx,md}\"" }, "author": "Simon Haenisch (https://github.com/simonhaenisch)", "repository": "simonhaenisch/rollup-plugin-typescript-paths", @@ -28,6 +29,7 @@ "prettier": "2.8.8", "prettier-plugin-organize-imports": "3.2.2", "rollup": "2.79.1", + "shx": "^0.3.4", "typescript": "5.1.3" }, "peerDependencies": {