All files / lib/internal/modules run_main.js

100% Statements 84/84
96.29% Branches 26/27
100% Functions 5/5
100% Lines 84/84

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 85139x 139x 139x 139x 139x 139x 139x 139x 139x 139x 139x 139x 139x 139x 4825x 4825x 4825x 4825x 4825x 4825x 4825x 4808x 4808x 4808x 4808x 4808x 4808x 4825x 139x 4825x 4825x 4825x 4825x 4825x 4825x 4825x 4825x 4795x 4825x 4825x 4825x 4825x 4658x 4825x 4825x 139x 151x 151x 151x 151x 151x 149x 149x 149x 151x 151x 139x 177x 177x 177x 177x 177x 130x 130x 177x 139x 139x 139x 139x 4825x 4825x 4825x 4825x 151x 4825x 4674x 4674x 4674x 4825x 139x 139x 139x 139x 139x  
'use strict';
 
const {
  ObjectCreate,
  StringPrototypeEndsWith,
} = primordials;
const CJSLoader = require('internal/modules/cjs/loader');
const { Module, toRealPath, readPackageScope } = CJSLoader;
const { getOptionValue } = require('internal/options');
const path = require('path');
const {
  handleProcessExit,
} = require('internal/modules/esm/handle_process_exit');
 
function resolveMainPath(main) {
  // Note extension resolution for the main entry point can be deprecated in a
  // future major.
  // Module._findPath is monkey-patchable here.
  let mainPath = Module._findPath(path.resolve(main), null, true);
  if (!mainPath)
    return;
 
  const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
  if (!preserveSymlinksMain)
    mainPath = toRealPath(mainPath);
 
  return mainPath;
}
 
function shouldUseESMLoader(mainPath) {
  const userLoader = getOptionValue('--experimental-loader');
  if (userLoader)
    return true;
  const esModuleSpecifierResolution =
    getOptionValue('--experimental-specifier-resolution');
  if (esModuleSpecifierResolution === 'node')
    return true;
  // Determine the module format of the main
  if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs'))
    return true;
  if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs'))
    return false;
  const pkg = readPackageScope(mainPath);
  return pkg && pkg.data.type === 'module';
}
 
function runMainESM(mainPath) {
  const { loadESM } = require('internal/process/esm_loader');
  const { pathToFileURL } = require('internal/url');
 
  handleMainPromise(loadESM((esmLoader) => {
    const main = path.isAbsolute(mainPath) ?
      pathToFileURL(mainPath).href : mainPath;
    return esmLoader.import(main, undefined, ObjectCreate(null));
  }));
}
 
async function handleMainPromise(promise) {
  process.on('exit', handleProcessExit);
  try {
    return await promise;
  } finally {
    process.off('exit', handleProcessExit);
  }
}
 
// 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.
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.
    Module._load(main, null, true);
  }
}
 
module.exports = {
  executeUserEntryPoint,
  handleMainPromise,
};