From 73d6792a059f7968c2535397b59d95eee5de7bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 16 May 2020 16:31:15 +0200 Subject: [PATCH] repl: support --loader option in builtin REPL Fixes: https://github.com/nodejs/node/issues/33435 PR-URL: https://github.com/nodejs/node/pull/33437 Reviewed-By: Gus Caplan Reviewed-By: Ruben Bridgewater --- lib/internal/main/repl.js | 49 ++++++++++--------- lib/internal/modules/run_main.js | 15 +----- lib/internal/process/esm_loader.js | 20 +++++++- .../esm_display_syntax_error_import.out | 1 + ...esm_display_syntax_error_import_module.out | 1 + test/message/esm_loader_not_found.out | 8 +-- .../esm_loader_not_found_cjs_hint_bare.out | 2 +- ...esm_loader_not_found_cjs_hint_relative.out | 8 +-- 8 files changed, 58 insertions(+), 46 deletions(-) diff --git a/lib/internal/main/repl.js b/lib/internal/main/repl.js index 693b7048a37f9c..a8356687ccedf5 100644 --- a/lib/internal/main/repl.js +++ b/lib/internal/main/repl.js @@ -7,6 +7,7 @@ const { prepareMainThreadExecution } = require('internal/bootstrap/pre_execution'); +const esmLoader = require('internal/process/esm_loader'); const { evalScript } = require('internal/process/execution'); @@ -32,31 +33,33 @@ if (process.env.NODE_REPL_EXTERNAL_MODULE) { process.exit(1); } - console.log(`Welcome to Node.js ${process.version}.\n` + - 'Type ".help" for more information.'); + esmLoader.loadESM(() => { + console.log(`Welcome to Node.js ${process.version}.\n` + + 'Type ".help" for more information.'); - const cliRepl = require('internal/repl'); - cliRepl.createInternalRepl(process.env, (err, repl) => { - if (err) { - throw err; - } - repl.on('exit', () => { - if (repl._flushing) { - repl.pause(); - return repl.once('flushHistory', () => { - process.exit(); - }); + const cliRepl = require('internal/repl'); + cliRepl.createInternalRepl(process.env, (err, repl) => { + if (err) { + throw err; } - process.exit(); + repl.on('exit', () => { + if (repl._flushing) { + repl.pause(); + return repl.once('flushHistory', () => { + process.exit(); + }); + } + process.exit(); + }); }); - }); - // If user passed '-e' or '--eval' along with `-i` or `--interactive`, - // evaluate the code in the current context. - if (getOptionValue('[has_eval_string]')) { - evalScript('[eval]', - getOptionValue('--eval'), - getOptionValue('--inspect-brk'), - getOptionValue('--print')); - } + // If user passed '-e' or '--eval' along with `-i` or `--interactive`, + // evaluate the code in the current context. + if (getOptionValue('[has_eval_string]')) { + evalScript('[eval]', + getOptionValue('--eval'), + getOptionValue('--inspect-brk'), + getOptionValue('--print')); + } + }); } diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index 5f8b1f53d33768..0967ef539ca20e 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -40,21 +40,10 @@ function shouldUseESMLoader(mainPath) { function runMainESM(mainPath) { const esmLoader = require('internal/process/esm_loader'); const { pathToFileURL } = require('internal/url'); - const { hasUncaughtExceptionCaptureCallback } = - require('internal/process/execution'); - return esmLoader.initializeLoader().then(() => { + esmLoader.loadESM((ESMLoader) => { const main = path.isAbsolute(mainPath) ? pathToFileURL(mainPath).href : mainPath; - return esmLoader.ESMLoader.import(main); - }).catch((e) => { - if (hasUncaughtExceptionCaptureCallback()) { - process._fatalException(e); - return; - } - internalBinding('errors').triggerUncaughtException( - e, - true /* fromPromise */ - ); + return ESMLoader.import(main); }); } diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index fe47098fde2f63..8f076b3ef32efd 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -4,6 +4,9 @@ const { ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, } = require('internal/errors').codes; const { Loader } = require('internal/modules/esm/loader'); +const { + hasUncaughtExceptionCaptureCallback, +} = require('internal/process/execution'); const { pathToFileURL } = require('internal/url'); const { getModuleFromWrap, @@ -34,7 +37,6 @@ exports.importModuleDynamicallyCallback = async function(wrap, specifier) { let ESMLoader = new Loader(); exports.ESMLoader = ESMLoader; -exports.initializeLoader = initializeLoader; async function initializeLoader() { const { getOptionValue } = require('internal/options'); const userLoader = getOptionValue('--experimental-loader'); @@ -59,3 +61,19 @@ async function initializeLoader() { return exports.ESMLoader = ESMLoader; })(); } + +exports.loadESM = async function loadESM(callback) { + try { + await initializeLoader(); + await callback(ESMLoader); + } catch (err) { + if (hasUncaughtExceptionCaptureCallback()) { + process._fatalException(err); + return; + } + internalBinding('errors').triggerUncaughtException( + err, + true /* fromPromise */ + ); + } +}; diff --git a/test/message/esm_display_syntax_error_import.out b/test/message/esm_display_syntax_error_import.out index 387a63a734b512..fe174d54a5c49f 100644 --- a/test/message/esm_display_syntax_error_import.out +++ b/test/message/esm_display_syntax_error_import.out @@ -5,3 +5,4 @@ SyntaxError: The requested module '../fixtures/es-module-loaders/module-named-ex at ModuleJob._instantiate (internal/modules/esm/module_job.js:*:*) at async ModuleJob.run (internal/modules/esm/module_job.js:*:*) at async Loader.import (internal/modules/esm/loader.js:*:*) + at async Object.loadESM (internal/process/esm_loader.js:*:*) diff --git a/test/message/esm_display_syntax_error_import_module.out b/test/message/esm_display_syntax_error_import_module.out index ae8b99d55fef20..d220627bd02654 100644 --- a/test/message/esm_display_syntax_error_import_module.out +++ b/test/message/esm_display_syntax_error_import_module.out @@ -5,3 +5,4 @@ SyntaxError: The requested module './module-named-exports.mjs' does not provide at ModuleJob._instantiate (internal/modules/esm/module_job.js:*:*) at async ModuleJob.run (internal/modules/esm/module_job.js:*:*) at async Loader.import (internal/modules/esm/loader.js:*:*) + at async Object.loadESM (internal/process/esm_loader.js:*:*) diff --git a/test/message/esm_loader_not_found.out b/test/message/esm_loader_not_found.out index 1d2aa957150082..60abb529a3c871 100644 --- a/test/message/esm_loader_not_found.out +++ b/test/message/esm_loader_not_found.out @@ -1,6 +1,6 @@ (node:*) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time (Use `node --trace-warnings ...` to show where the warning was created) -internal/modules/run_main.js:* +internal/process/esm_loader.js:* internalBinding('errors').triggerUncaughtException( ^ Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'i-dont-exist' imported from * @@ -11,8 +11,8 @@ Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'i-dont-exist' imported from * at Loader.getModuleJob (internal/modules/esm/loader.js:*:*) at Loader.import (internal/modules/esm/loader.js:*:*) at internal/process/esm_loader.js:*:* - at Object.initializeLoader (internal/process/esm_loader.js:*:*) - at runMainESM (internal/modules/run_main.js:*:*) - at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) { + at initializeLoader (internal/process/esm_loader.js:*:*) + at Object.loadESM (internal/process/esm_loader.js:*:*) + at runMainESM (internal/modules/run_main.js:*:*) { code: 'ERR_MODULE_NOT_FOUND' } diff --git a/test/message/esm_loader_not_found_cjs_hint_bare.out b/test/message/esm_loader_not_found_cjs_hint_bare.out index e56f1da0f6e76e..51a99cb29886bd 100644 --- a/test/message/esm_loader_not_found_cjs_hint_bare.out +++ b/test/message/esm_loader_not_found_cjs_hint_bare.out @@ -1,4 +1,4 @@ -internal/modules/run_main.js:* +internal/process/esm_loader.js:* internalBinding('errors').triggerUncaughtException( ^ diff --git a/test/message/esm_loader_not_found_cjs_hint_relative.out b/test/message/esm_loader_not_found_cjs_hint_relative.out index 76df3163bb728c..f7460c31416dc9 100644 --- a/test/message/esm_loader_not_found_cjs_hint_relative.out +++ b/test/message/esm_loader_not_found_cjs_hint_relative.out @@ -1,6 +1,6 @@ (node:*) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time (Use `node --trace-warnings ...` to show where the warning was created) -internal/modules/run_main.js:* +internal/process/esm_loader.js:* internalBinding('errors').triggerUncaughtException( ^ @@ -13,8 +13,8 @@ Did you mean to import ./test/common/fixtures.js? at Loader.getModuleJob (internal/modules/esm/loader.js:*:*) at Loader.import (internal/modules/esm/loader.js:*:*) at internal/process/esm_loader.js:*:* - at Object.initializeLoader (internal/process/esm_loader.js:*:*) - at runMainESM (internal/modules/run_main.js:*:*) - at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) { + at initializeLoader (internal/process/esm_loader.js:*:*) + at Object.loadESM (internal/process/esm_loader.js:*:*) + at runMainESM (internal/modules/run_main.js:*:*) { code: 'ERR_MODULE_NOT_FOUND' }