All files / lib/internal/process esm_loader.js

94.94% Statements 94/99
86.66% Branches 13/15
100% Functions 4/4
94.94% Lines 94/99

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 95 96 97 98 99 100134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 121x 121x 121x 121x 120x 120x 121x 134x 134x 134x 291x 291x 291x 291x 291x 290x 290x 290x 291x 1x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x     189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 189x 134x 134x 189x 189x 189x 189x 33x       33x 33x 33x 33x 33x 134x  
'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');
  // 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,
    ObjectCreate(null),
  );
 
  // 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 */
    );
  }
};