Skip to content

Commit

Permalink
fix: lazy-load repl to avoid domain side effects (#2025)
Browse files Browse the repository at this point in the history
* 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: #2024

* Update src/repl.ts

---------

Co-authored-by: Andrew Bradley <cspotcode@gmail.com>
  • Loading branch information
isaacs and cspotcode authored May 30, 2023
1 parent 7af5c48 commit 8f6f4e5
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/repl.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type * as _diff from 'diff';
import { homedir } from 'os';
import { join } from 'path';
import { Recoverable, ReplOptions, REPLServer, start as nodeReplStart } from 'repl';
import type * as _nodeRepl from 'repl';
import type { REPLServer, ReplOptions } from 'repl';
import { Context, createContext, Script } from 'vm';
import { Service, CreateOptions, TSError, env } from './index';
import { readFileSync, statSync } from 'fs';
Expand All @@ -28,6 +29,17 @@ function getDiffLines() {
return diff.diffLines;
}

// Lazy-loaded to prevent repl's require('domain') from causing problems
// https://github.com/TypeStrong/ts-node/issues/2024
// https://github.com/nodejs/node/issues/48131
let nodeRepl: typeof _nodeRepl;
function getNodeRepl() {
if (nodeRepl === undefined) {
nodeRepl = require('repl');
}
return nodeRepl;
}

/** @internal */
export const EVAL_FILENAME = `[eval].ts`;
/** @internal */
Expand Down Expand Up @@ -271,6 +283,7 @@ export function createRepl(options: CreateReplOptions = {}) {
const canLogTopLevelAwaitHint = service!.options.experimentalReplAwait !== false && !service!.shouldReplAwait;
if (error instanceof TSError) {
// Support recoverable compilations using >= node 6.
const { Recoverable } = getNodeRepl();
if (Recoverable && isRecoverable(error)) {
callback(new Recoverable(error));
return;
Expand Down Expand Up @@ -335,7 +348,7 @@ export function createRepl(options: CreateReplOptions = {}) {
// the REPL starts for a snappier user experience on startup.
service?.compile('', state.path);

const repl = nodeReplStart({
const repl = getNodeRepl().start({
prompt: '> ',
input: replService.stdin,
output: replService.stdout,
Expand Down

0 comments on commit 8f6f4e5

Please sign in to comment.