All files / lib/internal/process esm_loader.js

94.68% Statements 89/94
88.88% Branches 16/18
100% Functions 4/4
94.68% Lines 89/94

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 155x 155x 155x 155x 154x 154x 155x 138x 138x 138x 368x 368x 368x 368x 368x 367x 367x 367x 368x 1x 138x 138x 138x 138x 138x 138x 138x 138x 138x 138x 233x 233x 233x 233x 233x 36x 36x 36x 36x 36x     36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 34x 34x 34x 34x 233x 138x 138x 233x 233x 231x 233x 45x       45x 45x 45x 45x 45x 138x  
'use strict';
 
const {
  ObjectCreate,
} = primordials;
 
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 importModuleDynamicallyCallback(wrap, specifier, assertions) {
  const { callbackMap } = internalBinding('module_wrap');
  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();
};
 
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');
  const customLoaders = getOptionValue('--experimental-loader');
 
  if (customLoaders.length === 0) return;
 
  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 keyedExportsList = await internalEsmLoader.import(
    customLoaders,
    pathToFileURL(cwd).href,
    ObjectCreate(null),
  );
 
  // Hooks must then be added to external/public loader
  // (so they're triggered in userland)
  await esmLoader.addCustomLoaders(keyedExportsList);
}
 
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 */
    );
  }
};