Skip to content

Commit ba747b2

Browse files
committed
fix: lazy-load repl to avoid domain side effects
Actually starting the repl will still put the process into domain-mode, but this at least allows programs to use `ts-node` or `--loader=ts-node/esm` without losing the ability to use process.setUncaughtExceptionCaptureCallback(). The problem should ideally be fixed (or mitigated) in node core, but this is still worthwhile for the benefit of supporting current node versions. Re: nodejs/node#48131 Fix: TypeStrong#2024
1 parent 7af5c48 commit ba747b2

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

src/repl.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type * as _diff from 'diff';
22
import { homedir } from 'os';
33
import { join } from 'path';
4-
import { Recoverable, ReplOptions, REPLServer, start as nodeReplStart } from 'repl';
4+
import type * as _nodeRepl from 'repl';
5+
import type { REPLServer, ReplOptions } from 'repl';
56
import { Context, createContext, Script } from 'vm';
67
import { Service, CreateOptions, TSError, env } from './index';
78
import { readFileSync, statSync } from 'fs';
@@ -28,6 +29,26 @@ function getDiffLines() {
2829
return diff.diffLines;
2930
}
3031

32+
// Lazy-loaded to prevent repl's require('domain') from causing problems
33+
// https://github.com/TypeStrong/ts-node/issues/2024
34+
// https://github.com/nodejs/node/issues/48131
35+
let nodeRepl: {
36+
Recoverable: typeof _nodeRepl.Recoverable;
37+
REPLServer: typeof _nodeRepl.REPLServer;
38+
start: typeof _nodeRepl.start;
39+
};
40+
function getNodeRepl() {
41+
if (nodeRepl === undefined) {
42+
const { Recoverable, REPLServer, start } = require('repl') as {
43+
Recoverable: typeof _nodeRepl.Recoverable;
44+
REPLServer: typeof _nodeRepl.REPLServer;
45+
start: typeof _nodeRepl.start;
46+
};
47+
nodeRepl = { Recoverable, REPLServer, start };
48+
}
49+
return nodeRepl;
50+
}
51+
3152
/** @internal */
3253
export const EVAL_FILENAME = `[eval].ts`;
3354
/** @internal */
@@ -271,6 +292,7 @@ export function createRepl(options: CreateReplOptions = {}) {
271292
const canLogTopLevelAwaitHint = service!.options.experimentalReplAwait !== false && !service!.shouldReplAwait;
272293
if (error instanceof TSError) {
273294
// Support recoverable compilations using >= node 6.
295+
const { Recoverable } = getNodeRepl();
274296
if (Recoverable && isRecoverable(error)) {
275297
callback(new Recoverable(error));
276298
return;
@@ -335,7 +357,7 @@ export function createRepl(options: CreateReplOptions = {}) {
335357
// the REPL starts for a snappier user experience on startup.
336358
service?.compile('', state.path);
337359

338-
const repl = nodeReplStart({
360+
const repl = getNodeRepl().start({
339361
prompt: '> ',
340362
input: replService.stdin,
341363
output: replService.stdout,

0 commit comments

Comments
 (0)