I want to create a custom node REPL and make it work with typescript. As stated on ts-node documentations
nodeEval
nodeEval(code: string, context: any, _filename: string, callback: (err: null | > Error, result?: any) => any): void
Defined in src/repl.ts:91
eval implementation compatible with node's REPL API
Can be used in advanced scenarios if you want to manually create your own node > REPL instance and delegate eval to this ReplService.
Example:
import {start} from 'repl'; const replService: tsNode.ReplService = ...; // assuming you have already created a ts-node ReplService const nodeRepl = start({eval: replService.eval});Blockquote
Parameters
code: string
context: any
_filename: string
callback: (err: null | Error, result?: any) => any
(err: null | Error, result?: any): any
Parameters
err: null | Error
Optional result: any
Returns any
Returns void
nodeEval is a member of the ReplService class created with createRepl method. It seems to be compatible with the eval parameter that can be passed down to the start method.
So I wrote this:
import { start } from "repl";
import * as tsnode from "ts-node";
const tsNodeConfig = {
compilerOptions: {
target: "ES2017",
module: "commonjs",
},
};
tsnode.register({
compilerOptions: {
target: "ES2017",
module: "CommonJS",
},
});
const tsrepl: tsnode.ReplService = tsnode.createRepl({
stdin: process.stdin,
stdout: process.stdout,
});
const { nodeEval } = tsrepl;
tsnode.register(tsNodeConfig);
start({
prompt: "$ ",
ignoreUndefined: true,
eval: nodeEval,
});
I then run the code in the terminal where I created this repl.ts file and run ts-node repl.ts the shell starts, but it gives me this error when I enter any value like let foo = "bar":
Uncaught TypeError: Cannot read properties of undefined (reading 'options')
at REPLServer.Interface._ttyWrite (node:readline:1216:14)
at REPLServer.Interface._line (node:readline:864:8)
at REPLServer.Interface._onLine (node:readline:487:10)
at REPLServer.emit (node:domain:475:12)
at REPLServer.emit (node:events:527:28)
at REPLServer.onLine (node:repl:893:10)
at REPLServer.runBound [as eval] (node:domain:432:12)
at bound (node:domain:421:15)
at REPLServer.nodeEval (/Users/WAW/Documents/Projects/noiz-network-state/node_modules/ts-node/src/repl.ts:262:7)
at handleError (/Users/WAW/Documents/Projects/noiz-network-state/node_modules/ts-node/src/repl.ts:271:18)
$
If i pass down the object without the eval parameter, like this
start({
prompt: "$ ",
ignoreUndefined: true
});
the repl works as a node repl and it doesn't evaluate typescript code like type foo = string..
any idea??
I found the solution, in fact there is need to configure the ts-node repl service properly in order for this to work.
First we need to import
repl from node packagests from typescript npm packagets-node from packageimport repl from "repl";
import ts from "typescript";
import * as tsnode from "ts-node";
then we need to create a ts-node repl service like this:
const replService: tsnode.ReplService = tsnode.createRepl();
now we can actually create a service thanks to the evalAwarePartialHost member that is's inside the replService that we just created:
const service = tsnode.create({ ...replService.evalAwarePartialHost });
we then set the ts member of the service to be ts that we imported:
service.ts = ts;
now we have to set the service in the ts-node repl:
replService.setService(service);
now it's time to create the actual repl server:
const replServer = repl.start({
prompt: "$ ",
ignoreUndefined: true,
eval: replService.nodeEval,
});
the entire code looks like this:
import repl from "repl";
import ts from "typescript";
import * as tsnode from "ts-node";
// Create a ts-node replService
const replService: tsnode.ReplService = tsnode.createRepl();
const service = tsnode.create({ ...replService.evalAwarePartialHost });
service.ts = ts;
replService.setService(service);
// create a node-repl server
const replServer = repl.start({
prompt: "$ ",
ignoreUndefined: true,
eval: replService.nodeEval,
});
// setup environment
replServer.setupHistory(".log", () => {});
hope this can be helpfull for someone else!!
=)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With