Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/internal/modules/esm/get_format.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {

const experimentalNetworkImports =
getOptionValue('--experimental-network-imports');
const isESModule = !!getOptionValue('--module');
const { getPackageType, getPackageScopeConfig } = require('internal/modules/esm/resolve');
const { fileURLToPath } = require('internal/url');
const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
Expand Down Expand Up @@ -73,6 +74,9 @@ function extname(url) {
* @returns {string}
*/
function getFileProtocolModuleFormat(url, context, ignoreErrors) {
if (isESModule)
return 'module';
Comment thread
LiviaMedeiros marked this conversation as resolved.
Outdated

const ext = extname(url);
if (ext === '.js') {
return getPackageType(url) === 'module' ? 'module' : 'commonjs';
Expand Down
11 changes: 9 additions & 2 deletions lib/internal/modules/run_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ function shouldUseESMLoader(mainPath) {
return pkg && pkg.data.type === 'module';
}

function runMainESM(mainPath) {
function runMainESM(mainPath, isPath = true) {
const { loadESM } = require('internal/process/esm_loader');
const { pathToFileURL } = require('internal/url');

handleMainPromise(loadESM((esmLoader) => {
const main = path.isAbsolute(mainPath) ?
const main = isPath && path.isAbsolute(mainPath) ?
pathToFileURL(mainPath).href : mainPath;
return esmLoader.import(main, undefined, { __proto__: null });
}));
Expand All @@ -73,6 +73,13 @@ async function handleMainPromise(promise) {
// monkey-patchable code that belongs to the CJS loader (exposed by
// `require('module')`) even when the entry point is ESM.
function executeUserEntryPoint(main = process.argv[1]) {
const mainModule = getOptionValue('--module');
if (mainModule) {
const { pathToFileURL, URL } = require('internal/url');
const mainModuleURL = new URL(mainModule, pathToFileURL(process.cwd() + path.sep)).href;
return void runMainESM(mainModuleURL, false);
}

const resolvedMain = resolveMainPath(main);
const useESMLoader = shouldUseESMLoader(resolvedMain);
if (useESMLoader) {
Expand Down
3 changes: 2 additions & 1 deletion src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
return StartExecution(env, "internal/main/watch_mode");
}

if (!first_argv.empty() && first_argv != "-") {
if ((!first_argv.empty() && first_argv != "-") ||
env->options()->main_esm_module != "") {
return StartExecution(env, "internal/main/run_main_module");
}

Expand Down
3 changes: 3 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,9 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"ES module to preload (option can be repeated)",
&EnvironmentOptions::preload_esm_modules,
kAllowedInEnvvar);
AddOption("--module",
"Main ES module to load by absolute or relative URL",
&EnvironmentOptions::main_esm_module);
AddOption("--interactive",
"always enter the REPL even if stdin does not appear "
"to be a terminal",
Expand Down
2 changes: 2 additions & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ class EnvironmentOptions : public Options {

std::vector<std::string> preload_esm_modules;

std::string main_esm_module;

std::vector<std::string> user_argv;

inline DebugOptions* get_debug_options() { return &debug_options_; }
Expand Down