2019-11-10 16:59:16 +08:00
|
|
|
'use strict';
|
|
|
|
|
2020-11-07 11:08:09 +01:00
|
|
|
const {
|
2022-12-22 13:40:32 -08:00
|
|
|
StringPrototypeEndsWith,
|
2020-11-07 11:08:09 +01:00
|
|
|
} = primordials;
|
2022-12-22 13:40:32 -08:00
|
|
|
|
2019-11-10 16:59:16 +08:00
|
|
|
const { getOptionValue } = require('internal/options');
|
|
|
|
const path = require('path');
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Get the absolute path to the main entry point.
|
2023-10-01 08:26:56 +01:00
|
|
|
* @param {string} main - Entry point path
|
2023-09-18 19:48:24 -07:00
|
|
|
*/
|
2019-11-10 16:59:16 +08:00
|
|
|
function resolveMainPath(main) {
|
2023-10-05 10:57:32 -07:00
|
|
|
const defaultType = getOptionValue('--experimental-default-type');
|
|
|
|
/** @type {string} */
|
|
|
|
let mainPath;
|
|
|
|
if (defaultType === 'module') {
|
|
|
|
if (getOptionValue('--preserve-symlinks-main')) { return; }
|
|
|
|
mainPath = path.resolve(main);
|
|
|
|
} else {
|
|
|
|
// Extension searching for the main entry point is supported only in legacy mode.
|
|
|
|
// Module._findPath is monkey-patchable here.
|
|
|
|
const { Module } = require('internal/modules/cjs/loader');
|
|
|
|
mainPath = Module._findPath(path.resolve(main), null, true);
|
|
|
|
}
|
2023-09-15 12:18:13 -07:00
|
|
|
if (!mainPath) { return; }
|
2019-11-10 16:59:16 +08:00
|
|
|
|
|
|
|
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
|
2023-09-15 12:18:13 -07:00
|
|
|
if (!preserveSymlinksMain) {
|
2023-09-29 19:24:14 -07:00
|
|
|
const { toRealPath } = require('internal/modules/helpers');
|
2023-10-05 10:57:32 -07:00
|
|
|
try {
|
|
|
|
mainPath = toRealPath(mainPath);
|
|
|
|
} catch (err) {
|
|
|
|
if (defaultType === 'module' && err?.code === 'ENOENT') {
|
|
|
|
const { decorateErrorWithCommonJSHints } = require('internal/modules/esm/resolve');
|
|
|
|
const { getCWDURL } = require('internal/util');
|
|
|
|
decorateErrorWithCommonJSHints(err, mainPath, getCWDURL());
|
|
|
|
}
|
|
|
|
throw err;
|
|
|
|
}
|
2023-09-15 12:18:13 -07:00
|
|
|
}
|
2019-11-10 16:59:16 +08:00
|
|
|
|
|
|
|
return mainPath;
|
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Determine whether the main entry point should be loaded through the ESM Loader.
|
2023-10-01 08:26:56 +01:00
|
|
|
* @param {string} mainPath - Absolute path to the main entry point
|
2023-09-18 19:48:24 -07:00
|
|
|
*/
|
2022-12-22 13:40:32 -08:00
|
|
|
function shouldUseESMLoader(mainPath) {
|
2023-10-05 10:57:32 -07:00
|
|
|
if (getOptionValue('--experimental-default-type') === 'module') { return true; }
|
|
|
|
|
2022-12-22 13:40:32 -08:00
|
|
|
/**
|
|
|
|
* @type {string[]} userLoaders A list of custom loaders registered by the user
|
|
|
|
* (or an empty list when none have been registered).
|
|
|
|
*/
|
|
|
|
const userLoaders = getOptionValue('--experimental-loader');
|
|
|
|
/**
|
|
|
|
* @type {string[]} userImports A list of preloaded modules registered by the user
|
|
|
|
* (or an empty list when none have been registered).
|
|
|
|
*/
|
|
|
|
const userImports = getOptionValue('--import');
|
2023-09-15 12:18:13 -07:00
|
|
|
if (userLoaders.length > 0 || userImports.length > 0) { return true; }
|
2023-09-28 23:18:44 -07:00
|
|
|
|
|
|
|
// Determine the module format of the entry point.
|
2023-09-15 12:18:13 -07:00
|
|
|
if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs')) { return true; }
|
|
|
|
if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs')) { return false; }
|
2023-09-28 23:18:44 -07:00
|
|
|
|
2023-09-29 19:24:14 -07:00
|
|
|
const { readPackageScope } = require('internal/modules/package_json_reader');
|
2022-12-22 13:40:32 -08:00
|
|
|
const pkg = readPackageScope(mainPath);
|
2023-09-28 23:18:44 -07:00
|
|
|
// No need to guard `pkg` as it can only be an object or `false`.
|
|
|
|
return pkg.data?.type === 'module' || getOptionValue('--experimental-default-type') === 'module';
|
2022-12-22 13:40:32 -08:00
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Run the main entry point through the ESM Loader.
|
2023-10-01 08:26:56 +01:00
|
|
|
* @param {string} mainPath - Absolute path for the main entry point
|
2023-09-18 19:48:24 -07:00
|
|
|
*/
|
2019-11-10 16:59:16 +08:00
|
|
|
function runMainESM(mainPath) {
|
2021-08-25 22:55:14 +02:00
|
|
|
const { loadESM } = require('internal/process/esm_loader');
|
2019-11-10 16:59:16 +08:00
|
|
|
const { pathToFileURL } = require('internal/url');
|
2023-10-05 10:57:32 -07:00
|
|
|
const main = pathToFileURL(mainPath).href;
|
2021-08-25 22:55:14 +02:00
|
|
|
|
|
|
|
handleMainPromise(loadESM((esmLoader) => {
|
2023-01-09 21:38:36 -08:00
|
|
|
return esmLoader.import(main, undefined, { __proto__: null });
|
2020-08-06 02:56:17 +02:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Handle process exit events around the main entry point promise.
|
2023-10-01 08:26:56 +01:00
|
|
|
* @param {Promise} promise - Main entry point promise
|
2023-09-18 19:48:24 -07:00
|
|
|
*/
|
2021-05-12 12:16:43 +02:00
|
|
|
async function handleMainPromise(promise) {
|
2022-12-09 23:37:35 +01:00
|
|
|
const {
|
|
|
|
handleProcessExit,
|
|
|
|
} = require('internal/modules/esm/handle_process_exit');
|
2022-01-14 08:37:41 +08:00
|
|
|
process.on('exit', handleProcessExit);
|
2021-05-12 12:16:43 +02:00
|
|
|
try {
|
|
|
|
return await promise;
|
|
|
|
} finally {
|
2022-01-14 08:37:41 +08:00
|
|
|
process.off('exit', handleProcessExit);
|
2021-05-12 12:16:43 +02:00
|
|
|
}
|
2019-11-10 16:59:16 +08:00
|
|
|
}
|
|
|
|
|
2023-09-18 19:48:24 -07:00
|
|
|
/**
|
|
|
|
* Parse the CLI main entry point string and run it.
|
|
|
|
* For backwards compatibility, we have to run a bunch of monkey-patchable code that belongs to the CJS loader (exposed
|
|
|
|
* by `require('module')`) even when the entry point is ESM.
|
2023-10-05 10:57:32 -07:00
|
|
|
* This monkey-patchable code is bypassed under `--experimental-default-type=module`.
|
2023-10-01 08:26:56 +01:00
|
|
|
* Because of backwards compatibility, this function is exposed publicly via `import { runMain } from 'node:module'`.
|
2023-10-05 10:57:32 -07:00
|
|
|
* @param {string} main - First positional CLI argument, such as `'entry.js'` from `node entry.js`
|
2023-09-18 19:48:24 -07:00
|
|
|
*/
|
2019-11-10 16:59:16 +08:00
|
|
|
function executeUserEntryPoint(main = process.argv[1]) {
|
|
|
|
const resolvedMain = resolveMainPath(main);
|
|
|
|
const useESMLoader = shouldUseESMLoader(resolvedMain);
|
|
|
|
if (useESMLoader) {
|
|
|
|
runMainESM(resolvedMain || main);
|
|
|
|
} else {
|
|
|
|
// Module._load is the monkey-patchable CJS module loader.
|
2022-12-13 22:35:42 +01:00
|
|
|
const { Module } = require('internal/modules/cjs/loader');
|
2019-11-10 16:59:16 +08:00
|
|
|
Module._load(main, null, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
2020-08-06 02:56:17 +02:00
|
|
|
executeUserEntryPoint,
|
|
|
|
handleMainPromise,
|
2019-11-10 16:59:16 +08:00
|
|
|
};
|