From 61d1dfdfec5ff521222cc12d5da8d150ff420a7a Mon Sep 17 00:00:00 2001 From: Ron S Date: Fri, 21 Oct 2022 13:15:53 -0400 Subject: [PATCH] fix: Edge cases exist which causes ts-node to fail with register script (fixes #162) --- src/transformer.ts | 49 ++++++++++++++++-------------- src/types.ts | 9 ++++-- src/utils/ts-helpers.ts | 2 +- test/projects/extras/tsconfig.json | 2 +- test/tests/extras.test.ts | 15 ++++++--- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/transformer.ts b/src/transformer.ts index 4ae8bc3..c6e5f94 100755 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -1,6 +1,6 @@ import path from "path"; import ts, { CompilerOptions } from "typescript"; -import { RunMode, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types"; +import { RunMode, TsNodeState, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types"; import { nodeVisitor } from "./visitor"; import { createHarmonyFactory } from "./harmony"; import { Minimatch } from "minimatch"; @@ -16,6 +16,7 @@ function getTsProperties(args: Parameters) { let fileNames: readonly string[] | undefined; let compilerOptions: CompilerOptions; let runMode: RunMode; + let tsNodeState: TsNodeState | undefined; const { 0: program, 2: extras, 3: manualTransformOptions } = args; @@ -25,13 +26,11 @@ function getTsProperties(args: Parameters) { /* Determine RunMode & Setup */ // Note: ts-node passes a Program with the paths property stripped, so we do some comparison to determine if it's the caller - const maybeIsTsNode = - tsNodeProps && - (!program || - (compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath && !compilerOptions!.paths)); + const isTsNode = + tsNodeProps && (!program || compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath); // RunMode: Program - if (program && !maybeIsTsNode) { + if (program && !isTsNode) { runMode = RunMode.Program; compilerOptions = compilerOptions!; } @@ -42,18 +41,24 @@ function getTsProperties(args: Parameters) { compilerOptions = manualTransformOptions.compilerOptions!; } // RunMode: TsNode - else if (maybeIsTsNode) { + else if (isTsNode) { fileNames = tsNodeProps.fileNames; - - runMode = - !program || (fileNames.length > 1 && program.getRootFileNames().length === 1) - ? RunMode.TsNodeTranspileOnly - : RunMode.TsNode; - - compilerOptions = { - ...(program?.getCompilerOptions() ?? {}), - ...tsNodeProps!.compilerOptions - }; + runMode = RunMode.TsNode; + + tsNodeState = + !program || + (fileNames.length > 1 && program?.getRootFileNames().length === 1) || + (!compilerOptions!.paths && tsNodeProps!.compilerOptions.paths) + ? TsNodeState.Stripped + : TsNodeState.Full; + + compilerOptions = + tsNodeState === TsNodeState.Full + ? compilerOptions! + : { + ...(program?.getCompilerOptions() ?? {}), + ...tsNodeProps!.compilerOptions, + }; } else { throw new Error( `Cannot transform without a Program, ts-node instance, or manual parameters supplied. ` + @@ -61,7 +66,7 @@ function getTsProperties(args: Parameters) { ); } - return { tsInstance, compilerOptions, fileNames, runMode }; + return { tsInstance, compilerOptions, fileNames, runMode, tsNodeState }; } // endregion @@ -88,7 +93,8 @@ export default function transformer( tsInstance, compilerOptions, fileNames, - runMode + runMode, + tsNodeState } = getTsProperties([ program, pluginConfig, transformerExtras, manualTransformOptions ]); const rootDirs = compilerOptions.rootDirs?.filter(path.isAbsolute); @@ -97,14 +103,12 @@ export default function transformer( /* Add supplements for various run modes */ let emitHost = transformationContext.getEmitHost(); - if (!emitHost || runMode === RunMode.TsNodeTranspileOnly) { + if (!emitHost || tsNodeState === TsNodeState.Stripped) { if (!fileNames) throw new Error( `No EmitHost found and could not determine files to be processed. Please file an issue with a reproduction!` ); emitHost = createSyntheticEmitHost(compilerOptions, tsInstance, getCanonicalFileName, fileNames as string[]); - } else if (runMode === RunMode.TsNode) { - Object.assign(emitHost, { getCompilerOptions: () => compilerOptions }); } /* Create Visitor Context */ @@ -125,6 +129,7 @@ export default function transformer( tsVersionMinor, emitHost, runMode, + tsNodeState, excludeMatchers: config.exclude?.map((globPattern) => new Minimatch(globPattern, { matchBase: true })), outputFileNamesCache: new Map(), // Get paths patterns appropriate for TS compiler version diff --git a/src/types.ts b/src/types.ts index 4d13b95..6b63131 100755 --- a/src/types.ts +++ b/src/types.ts @@ -36,6 +36,7 @@ export interface TsTransformPathsContext { readonly tsVersionMinor: number; readonly tsFactory?: ts.NodeFactory; readonly runMode: RunMode; + readonly tsNodeState?: TsNodeState; readonly program?: ts.Program; readonly config: TsTransformPathsConfig; readonly compilerOptions: CompilerOptions; @@ -64,9 +65,13 @@ export interface VisitorContext extends TsTransformPathsContext { export enum RunMode { TsNode = "ts-node", - TsNodeTranspileOnly = "ts-node-transpile-only", Manual = "manual", - Program = "program" + Program = "program", +} + +export enum TsNodeState { + Full, + Stripped, } // endregion diff --git a/src/utils/ts-helpers.ts b/src/utils/ts-helpers.ts index e0f3bf0..88b8af7 100755 --- a/src/utils/ts-helpers.ts +++ b/src/utils/ts-helpers.ts @@ -100,7 +100,7 @@ export function getTsNodeRegistrationProperties(tsInstance: typeof ts) { const fileNames = pcl?.fileNames || config.fileNames; const compilerOptions = Object.assign(config.options, options.compilerOptions, { outDir: pcl?.options.outDir }); - return { compilerOptions, fileNames }; + return { compilerOptions, fileNames, tsNodeOptions: options }; } // endregion diff --git a/test/projects/extras/tsconfig.json b/test/projects/extras/tsconfig.json index bc6d2b9..f41803b 100755 --- a/test/projects/extras/tsconfig.json +++ b/test/projects/extras/tsconfig.json @@ -2,12 +2,12 @@ "include": [ "src" ], "ts-node": { - "transpileOnly": true, "require": [ "typescript-transform-paths/register" ] }, "compilerOptions": { "noEmit": true, + "outDir": "dist", "rootDir": ".", "module": "CommonJS", diff --git a/test/tests/extras.test.ts b/test/tests/extras.test.ts index 4a9c280..3730873 100755 --- a/test/tests/extras.test.ts +++ b/test/tests/extras.test.ts @@ -33,9 +33,16 @@ describe(`Extra Tests`, () => { } }); - test(`Register script transforms with ts-node`, () => { - const res = execSync("npx ts-node src/index.ts", { cwd: projectRoot }).toString(); - expect(res).toMatch(/^null($|\r?\n)/); - }); + describe(`ts-node register script`, () => { + test(`Works with --transpileOnly`, () => { + const res = execSync("npx ts-node --transpileOnly src/index.ts", { cwd: projectRoot }).toString(); + expect(res).toMatch(/^null($|\r?\n)/); + }); + + test(`Works with --typeCheck`, () => { + const res = execSync("npx ts-node --typeCheck src/index.ts", { cwd: projectRoot }).toString(); + expect(res).toMatch(/^null($|\r?\n)/); + }); + }) }); });