mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 17:51:35 +00:00

doc: update ESM hook examples esm: fix unsafe primordial doc: fix ESM example linting esm: allow source of type ArrayBuffer doc: update ESM hook changelog to include resolve format esm: allow all ArrayBuffers and TypedArrays for load hook source doc: tidy code & API docs doc: convert ESM source table header from Title Case to Sentence case doc: add detailed explanation for getPackageType esm: add caveat that ESMLoader::import() must NOT be renamed esm: tidy code declaration of getFormat protocolHandlers doc: correct ESM doc link (bad conflict resolution) doc: update ESM hook limitation for CJS esm: tweak preload description doc: update ESM getPackageType() example explanation PR-URL: https://github.com/nodejs/node/pull/37468 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
94 lines
2.7 KiB
JavaScript
94 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
|
|
} = require('internal/errors').codes;
|
|
const { ESMLoader } = require('internal/modules/esm/loader');
|
|
const {
|
|
hasUncaughtExceptionCaptureCallback,
|
|
} = require('internal/process/execution');
|
|
const { pathToFileURL } = require('internal/url');
|
|
const {
|
|
getModuleFromWrap,
|
|
} = require('internal/vm/module');
|
|
|
|
exports.initializeImportMetaObject = function(wrap, meta) {
|
|
const { callbackMap } = internalBinding('module_wrap');
|
|
if (callbackMap.has(wrap)) {
|
|
const { initializeImportMeta } = callbackMap.get(wrap);
|
|
if (initializeImportMeta !== undefined) {
|
|
initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.importModuleDynamicallyCallback = async function(wrap, specifier) {
|
|
const { callbackMap } = internalBinding('module_wrap');
|
|
if (callbackMap.has(wrap)) {
|
|
const { importModuleDynamically } = callbackMap.get(wrap);
|
|
if (importModuleDynamically !== undefined) {
|
|
return importModuleDynamically(
|
|
specifier, getModuleFromWrap(wrap) || wrap);
|
|
}
|
|
}
|
|
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
|
};
|
|
|
|
const esmLoader = new ESMLoader();
|
|
|
|
exports.esmLoader = esmLoader;
|
|
|
|
/**
|
|
* Causes side-effects: user-defined loader hooks are added to esmLoader.
|
|
* @returns {void}
|
|
*/
|
|
async function initializeLoader() {
|
|
const { getOptionValue } = require('internal/options');
|
|
// customLoaders CURRENTLY can be only 1 (a string)
|
|
// Once chaining is implemented, it will be string[]
|
|
const customLoaders = getOptionValue('--experimental-loader');
|
|
|
|
if (!customLoaders.length) return;
|
|
|
|
const { emitExperimentalWarning } = require('internal/util');
|
|
emitExperimentalWarning('--experimental-loader');
|
|
|
|
let cwd;
|
|
try {
|
|
cwd = process.cwd() + '/';
|
|
} catch {
|
|
cwd = 'file:///';
|
|
}
|
|
|
|
// A separate loader instance is necessary to avoid cross-contamination
|
|
// between internal Node.js and userland. For example, a module with internal
|
|
// state (such as a counter) should be independent.
|
|
const internalEsmLoader = new ESMLoader();
|
|
|
|
// Importation must be handled by internal loader to avoid poluting userland
|
|
const exports = await internalEsmLoader.import(
|
|
customLoaders,
|
|
pathToFileURL(cwd).href,
|
|
);
|
|
|
|
// Hooks must then be added to external/public loader
|
|
// (so they're triggered in userland)
|
|
await esmLoader.addCustomLoaders(exports);
|
|
}
|
|
|
|
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 */
|
|
);
|
|
}
|
|
};
|