Skip to content

Commit 09f79e2

Browse files
committed
fix: Edge cases exist which causes ts-node to fail with register script (fixes #162)
1 parent 1ab99cd commit 09f79e2

File tree

5 files changed

+46
-20
lines changed

5 files changed

+46
-20
lines changed

src/transformer.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from "path";
22
import ts, { CompilerOptions } from "typescript";
3-
import { RunMode, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types";
3+
import { RunMode, TsNodeState, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types";
44
import { nodeVisitor } from "./visitor";
55
import { createHarmonyFactory } from "./harmony";
66
import { Minimatch } from "minimatch";
@@ -16,6 +16,7 @@ function getTsProperties(args: Parameters<typeof transformer>) {
1616
let fileNames: readonly string[] | undefined;
1717
let compilerOptions: CompilerOptions;
1818
let runMode: RunMode;
19+
let tsNodeState: TsNodeState | undefined;
1920

2021
const { 0: program, 2: extras, 3: manualTransformOptions } = args;
2122

@@ -25,13 +26,11 @@ function getTsProperties(args: Parameters<typeof transformer>) {
2526

2627
/* Determine RunMode & Setup */
2728
// Note: ts-node passes a Program with the paths property stripped, so we do some comparison to determine if it's the caller
28-
const maybeIsTsNode =
29-
tsNodeProps &&
30-
(!program ||
31-
(compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath && !compilerOptions!.paths));
29+
const isTsNode =
30+
tsNodeProps && (!program || compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath);
3231

3332
// RunMode: Program
34-
if (program && !maybeIsTsNode) {
33+
if (program && !isTsNode) {
3534
runMode = RunMode.Program;
3635
compilerOptions = compilerOptions!;
3736
}
@@ -42,18 +41,32 @@ function getTsProperties(args: Parameters<typeof transformer>) {
4241
compilerOptions = manualTransformOptions.compilerOptions!;
4342
}
4443
// RunMode: TsNode
45-
else if (maybeIsTsNode) {
46-
runMode = RunMode.TsNode;
44+
else if (isTsNode) {
4745
fileNames = tsNodeProps.fileNames;
48-
compilerOptions = tsNodeProps.compilerOptions;
46+
runMode = RunMode.TsNode;
47+
48+
tsNodeState =
49+
!program ||
50+
(fileNames.length > 1 && program?.getRootFileNames().length === 1) ||
51+
(!compilerOptions!.paths && tsNodeProps!.compilerOptions.paths)
52+
? TsNodeState.Stripped
53+
: TsNodeState.Full;
54+
55+
compilerOptions =
56+
tsNodeState === TsNodeState.Full
57+
? compilerOptions!
58+
: {
59+
...(program?.getCompilerOptions() ?? {}),
60+
...tsNodeProps!.compilerOptions,
61+
};
4962
} else {
5063
throw new Error(
5164
`Cannot transform without a Program, ts-node instance, or manual parameters supplied. ` +
5265
`Make sure you're using ts-patch or ts-node with transpileOnly.`
5366
);
5467
}
5568

56-
return { tsInstance, compilerOptions, fileNames, runMode };
69+
return { tsInstance, compilerOptions, fileNames, runMode, tsNodeState };
5770
}
5871

5972
// endregion
@@ -80,7 +93,8 @@ export default function transformer(
8093
tsInstance,
8194
compilerOptions,
8295
fileNames,
83-
runMode
96+
runMode,
97+
tsNodeState
8498
} = getTsProperties([ program, pluginConfig, transformerExtras, manualTransformOptions ]);
8599

86100
const rootDirs = compilerOptions.rootDirs?.filter(path.isAbsolute);
@@ -89,14 +103,12 @@ export default function transformer(
89103

90104
/* Add supplements for various run modes */
91105
let emitHost = transformationContext.getEmitHost();
92-
if (!emitHost) {
106+
if (!emitHost || tsNodeState === TsNodeState.Stripped) {
93107
if (!fileNames)
94108
throw new Error(
95109
`No EmitHost found and could not determine files to be processed. Please file an issue with a reproduction!`
96110
);
97111
emitHost = createSyntheticEmitHost(compilerOptions, tsInstance, getCanonicalFileName, fileNames as string[]);
98-
} else if (runMode === RunMode.TsNode) {
99-
Object.assign(emitHost, { getCompilerOptions: () => compilerOptions });
100112
}
101113

102114
/* Create Visitor Context */
@@ -117,6 +129,7 @@ export default function transformer(
117129
tsVersionMinor,
118130
emitHost,
119131
runMode,
132+
tsNodeState,
120133
excludeMatchers: config.exclude?.map((globPattern) => new Minimatch(globPattern, { matchBase: true })),
121134
outputFileNamesCache: new Map(),
122135
// Get paths patterns appropriate for TS compiler version

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface TsTransformPathsContext {
3636
readonly tsVersionMinor: number;
3737
readonly tsFactory?: ts.NodeFactory;
3838
readonly runMode: RunMode;
39+
readonly tsNodeState?: TsNodeState;
3940
readonly program?: ts.Program;
4041
readonly config: TsTransformPathsConfig;
4142
readonly compilerOptions: CompilerOptions;
@@ -68,4 +69,9 @@ export enum RunMode {
6869
Program = "program",
6970
}
7071

72+
export enum TsNodeState {
73+
Full,
74+
Stripped,
75+
}
76+
7177
// endregion

src/utils/ts-helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function getTsNodeRegistrationProperties(tsInstance: typeof ts) {
100100
const fileNames = pcl?.fileNames || config.fileNames;
101101
const compilerOptions = Object.assign(config.options, options.compilerOptions, { outDir: pcl?.options.outDir });
102102

103-
return { compilerOptions, fileNames };
103+
return { compilerOptions, fileNames, tsNodeOptions: options };
104104
}
105105

106106
// endregion

test/projects/extras/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
"include": [ "src" ],
33

44
"ts-node": {
5-
"transpileOnly": true,
65
"require": [ "typescript-transform-paths/register" ]
76
},
87

98
"compilerOptions": {
109
"noEmit": true,
10+
"outDir": "dist",
1111

1212
"rootDir": ".",
1313
"module": "CommonJS",

test/tests/extras.test.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ describe(`Extra Tests`, () => {
3333
}
3434
});
3535

36-
test(`Register script transforms with ts-node`, () => {
37-
const res = execSync("npx ts-node src/index.ts", { cwd: projectRoot }).toString();
38-
expect(res).toMatch(/^null($|\r?\n)/);
39-
});
36+
describe(`ts-node register script`, () => {
37+
test(`Works with --transpileOnly`, () => {
38+
const res = execSync("npx ts-node --transpileOnly src/index.ts", { cwd: projectRoot }).toString();
39+
expect(res).toMatch(/^null($|\r?\n)/);
40+
});
41+
42+
test(`Works with --typeCheck`, () => {
43+
const res = execSync("npx ts-node --typeCheck src/index.ts", { cwd: projectRoot }).toString();
44+
expect(res).toMatch(/^null($|\r?\n)/);
45+
});
46+
})
4047
});
4148
});

0 commit comments

Comments
 (0)