diff --git a/lib/repl.js b/lib/repl.js index d9efb8c5ece523..44a265a2cca34e 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -234,10 +234,14 @@ function REPLServer(prompt, throw new ERR_INVALID_REPL_EVAL_CONFIG(); } - // Add this listener only once and use a WeakSet that contains the REPLs - // domains. Otherwise we'd have to add a single listener to each REPL instance - // and that could trigger the `MaxListenersExceededWarning`. - if (!options[kStandaloneREPL] && !addedNewListener) { + if (options[kStandaloneREPL]) { + // It is possible to introspect the running REPL accessing this variable + // from inside the REPL. This is useful for anyone working on the REPL. + exports.repl = this; + } else if (!addedNewListener) { + // Add this listener only once and use a WeakSet that contains the REPLs + // domains. Otherwise we'd have to add a single listener to each REPL + // instance and that could trigger the `MaxListenersExceededWarning`. process.prependListener('newListener', (event, listener) => { if (event === 'uncaughtException' && process.domain && @@ -895,14 +899,8 @@ exports.start = function(prompt, useGlobal, ignoreUndefined, replMode) { - const repl = new REPLServer(prompt, - source, - eval_, - useGlobal, - ignoreUndefined, - replMode); - if (!exports.repl) exports.repl = repl; - return repl; + return new REPLServer( + prompt, source, eval_, useGlobal, ignoreUndefined, replMode); }; REPLServer.prototype.setupHistory = function setupHistory(historyFile, cb) { diff --git a/test/parallel/test-repl-options.js b/test/parallel/test-repl-options.js index 43270e7412d3a2..99f9fa8a605142 100644 --- a/test/parallel/test-repl-options.js +++ b/test/parallel/test-repl-options.js @@ -24,6 +24,9 @@ const common = require('../common'); const ArrayStream = require('../common/arraystream'); const assert = require('assert'); const repl = require('repl'); +const cp = require('child_process'); + +assert.strictEqual(repl.repl, undefined); common.expectWarning({ DeprecationWarning: { @@ -120,3 +123,25 @@ assert.strictEqual(r4.ignoreUndefined, false); assert.strictEqual(r4.replMode, repl.REPL_MODE_SLOPPY); assert.strictEqual(r4.historySize, 30); r4.close(); + +// Check the standalone REPL +{ + const child = cp.spawn(process.execPath, ['--interactive']); + let output = ''; + + child.stdout.setEncoding('utf8'); + child.stdout.on('data', (data) => { + output += data; + }); + + child.on('exit', common.mustCall(() => { + const results = output.replace(/^> /mg, '').split('\n').slice(2); + assert.deepStrictEqual(results, ['undefined', '']); + })); + + child.stdin.write( + 'assert.ok(util.inspect(repl.repl, {depth: -1}).includes("REPLServer"));\n' + ); + child.stdin.write('.exit'); + child.stdin.end(); +} diff --git a/test/parallel/test-repl-reverse-search.js b/test/parallel/test-repl-reverse-search.js index a7c736300188de..baafdc9d8fbd33 100644 --- a/test/parallel/test-repl-reverse-search.js +++ b/test/parallel/test-repl-reverse-search.js @@ -251,8 +251,8 @@ const tests = [ '\x1B[1G', '\x1B[0J', `${prompt}ab = "aaaa"`, '\x1B[14G', '\x1B[1G', '\x1B[0J', - `${prompt}repl.repl.historyIndex`, '\x1B[25G', '\n// -1', - '\x1B[19C\x1B[1A', + `${prompt}repl.repl.historyIndex`, '\x1B[25G', '\n// 8', + '\x1B[20C\x1B[1A', '\x1B[1B', '\x1B[2K', '\x1B[1A', '\nfwd-i-search: _', '\x1B[1A', '\x1B[25G', '\x1B[3G', '\x1B[0J',