mirror of
https://github.com/nodejs/node.git
synced 2025-05-05 18:57:34 +00:00

PR-URL: https://github.com/nodejs/node/pull/49144 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
160 lines
4.5 KiB
JavaScript
160 lines
4.5 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ArrayIsArray,
|
|
SafeSet,
|
|
SafeWeakMap,
|
|
ObjectFreeze,
|
|
} = primordials;
|
|
|
|
const {
|
|
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
|
|
ERR_INVALID_ARG_VALUE,
|
|
} = require('internal/errors').codes;
|
|
const { getOptionValue } = require('internal/options');
|
|
const {
|
|
loadPreloadModules,
|
|
initializeFrozenIntrinsics,
|
|
} = require('internal/process/pre_execution');
|
|
const { pathToFileURL } = require('internal/url');
|
|
const {
|
|
setImportModuleDynamicallyCallback,
|
|
setInitializeImportMetaObjectCallback,
|
|
} = internalBinding('module_wrap');
|
|
const {
|
|
getModuleFromWrap,
|
|
} = require('internal/vm/module');
|
|
const assert = require('internal/assert');
|
|
|
|
const callbackMap = new SafeWeakMap();
|
|
function setCallbackForWrap(wrap, data) {
|
|
callbackMap.set(wrap, data);
|
|
}
|
|
|
|
let defaultConditions;
|
|
function getDefaultConditions() {
|
|
assert(defaultConditions !== undefined);
|
|
return defaultConditions;
|
|
}
|
|
|
|
let defaultConditionsSet;
|
|
function getDefaultConditionsSet() {
|
|
assert(defaultConditionsSet !== undefined);
|
|
return defaultConditionsSet;
|
|
}
|
|
|
|
// This function is called during pre-execution, before any user code is run.
|
|
function initializeDefaultConditions() {
|
|
const userConditions = getOptionValue('--conditions');
|
|
const noAddons = getOptionValue('--no-addons');
|
|
const addonConditions = noAddons ? [] : ['node-addons'];
|
|
|
|
defaultConditions = ObjectFreeze([
|
|
'node',
|
|
'import',
|
|
...addonConditions,
|
|
...userConditions,
|
|
]);
|
|
defaultConditionsSet = new SafeSet(defaultConditions);
|
|
}
|
|
|
|
/**
|
|
* @param {string[]} [conditions]
|
|
* @returns {Set<string>}
|
|
*/
|
|
function getConditionsSet(conditions) {
|
|
if (conditions !== undefined && conditions !== getDefaultConditions()) {
|
|
if (!ArrayIsArray(conditions)) {
|
|
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
|
|
'expected an array');
|
|
}
|
|
return new SafeSet(conditions);
|
|
}
|
|
return getDefaultConditionsSet();
|
|
}
|
|
|
|
function initializeImportMetaObject(wrap, meta) {
|
|
if (callbackMap.has(wrap)) {
|
|
const { initializeImportMeta } = callbackMap.get(wrap);
|
|
if (initializeImportMeta !== undefined) {
|
|
meta = initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
|
|
if (callbackMap.has(wrap)) {
|
|
const { importModuleDynamically } = callbackMap.get(wrap);
|
|
if (importModuleDynamically !== undefined) {
|
|
return importModuleDynamically(
|
|
specifier, getModuleFromWrap(wrap) || wrap, assertions);
|
|
}
|
|
}
|
|
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
|
}
|
|
|
|
// This is configured during pre-execution. Specifically it's set to true for
|
|
// the loader worker in internal/main/worker_thread.js.
|
|
let _isLoaderWorker = false;
|
|
function initializeESM(isLoaderWorker = false) {
|
|
_isLoaderWorker = isLoaderWorker;
|
|
initializeDefaultConditions();
|
|
// Setup per-isolate callbacks that locate data or callbacks that we keep
|
|
// track of for different ESM modules.
|
|
setInitializeImportMetaObjectCallback(initializeImportMetaObject);
|
|
setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);
|
|
}
|
|
|
|
function isLoaderWorker() {
|
|
return _isLoaderWorker;
|
|
}
|
|
|
|
async function initializeHooks() {
|
|
const customLoaderURLs = getOptionValue('--experimental-loader');
|
|
|
|
let cwd;
|
|
try {
|
|
// `process.cwd()` can fail if the parent directory is deleted while the process runs.
|
|
cwd = process.cwd() + '/';
|
|
} catch {
|
|
cwd = '/';
|
|
}
|
|
|
|
|
|
const { Hooks } = require('internal/modules/esm/hooks');
|
|
const esmLoader = require('internal/process/esm_loader').esmLoader;
|
|
|
|
const hooks = new Hooks();
|
|
esmLoader.setCustomizations(hooks);
|
|
|
|
// We need the loader customizations to be set _before_ we start invoking
|
|
// `--require`, otherwise loops can happen because a `--require` script
|
|
// might call `register(...)` before we've installed ourselves. These
|
|
// global values are magically set in `setupUserModules` just for us and
|
|
// we call them in the correct order.
|
|
// N.B. This block appears here specifically in order to ensure that
|
|
// `--require` calls occur before `--loader` ones do.
|
|
loadPreloadModules();
|
|
initializeFrozenIntrinsics();
|
|
|
|
const parentURL = pathToFileURL(cwd).href;
|
|
for (let i = 0; i < customLoaderURLs.length; i++) {
|
|
await hooks.register(
|
|
customLoaderURLs[i],
|
|
parentURL,
|
|
);
|
|
}
|
|
|
|
return hooks;
|
|
}
|
|
|
|
module.exports = {
|
|
setCallbackForWrap,
|
|
initializeESM,
|
|
initializeHooks,
|
|
getDefaultConditions,
|
|
getConditionsSet,
|
|
loaderWorkerId: 'internal/modules/esm/worker',
|
|
isLoaderWorker,
|
|
};
|