Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: add --module option #49295

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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 && context.parentURL === undefined)
return 'module';

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