Search code examples
javascriptnode.jsread-eval-print-loopdeno

How can I start a REPL that can access local variables in node.js?


Just like from IPython import embed; embed() but for node.

I want to open a REPL shell programmatically and be able to at least read the local variables. Being able to change them as well is a plus.


Solution

  • You can build a REPL similar to the built-in Deno REPL and and evaluate expressions using the dangerous eval function. Through it you'll be able to access local variables and other things (e.g. window).

    repl.ts

    import { readLines, writeAll } from "https://deno.land/[email protected]/io/mod.ts";
    
    export default async function repl(evaluate: (x: string) => unknown) {
      await writeOutput("exit using ctrl+d or close()\n");
      await writeOutput("> ");
      for await (const input of readInputs()) {
        try {
          const value = evaluate(input);
          const output = `${Deno.inspect(value, { colors: !Deno.noColor })}\n`;
          await writeOutput(output);
          await writeOutput("> ");
        } catch (error) {
          await writeError(error);
        }
      }
    }
    
    async function* readInputs(): AsyncIterableIterator<string> {
      yield* readLines(Deno.stdin);
    }
    
    async function writeOutput(output: string) {
      await writeAll(Deno.stdout, new TextEncoder().encode(output));
    }
    
    async function writeError(error: unknown) {
      await writeAll(Deno.stderr, new TextEncoder().encode(`Uncaught ${error}\n`));
    }
    

    repl_demo.ts

    import repl from "./repl.ts";
    
    let a = 1;
    let b = 2;
    let c = 3;
    
    await repl((x) => eval(x));
    

    example usage

    % deno run repl_demo.ts
    exit using ctrl+d or close()
    > a
    1
    > a = 40
    40
    > a + b
    42