1'use strict'; 2 3const CJSLoader = require('internal/modules/cjs/loader'); 4const { Module, toRealPath, readPackageScope } = CJSLoader; 5const { getOptionValue } = require('internal/options'); 6const path = require('path'); 7 8function resolveMainPath(main) { 9 // Note extension resolution for the main entry point can be deprecated in a 10 // future major. 11 // Module._findPath is monkey-patchable here. 12 let mainPath = Module._findPath(path.resolve(main), null, true); 13 if (!mainPath) 14 return; 15 16 const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); 17 if (!preserveSymlinksMain) 18 mainPath = toRealPath(mainPath); 19 20 return mainPath; 21} 22 23function shouldUseESMLoader(mainPath) { 24 const userLoader = getOptionValue('--experimental-loader'); 25 if (userLoader) 26 return true; 27 const experimentalSpecifierResolution = 28 getOptionValue('--experimental-specifier-resolution'); 29 if (experimentalSpecifierResolution === 'node') 30 return true; 31 // Determine the module format of the main 32 if (mainPath && mainPath.endsWith('.mjs')) 33 return true; 34 if (!mainPath || mainPath.endsWith('.cjs')) 35 return false; 36 const pkg = readPackageScope(mainPath); 37 return pkg && pkg.data.type === 'module'; 38} 39 40function runMainESM(mainPath) { 41 const esmLoader = require('internal/process/esm_loader'); 42 const { pathToFileURL } = require('internal/url'); 43 esmLoader.loadESM((ESMLoader) => { 44 const main = path.isAbsolute(mainPath) ? 45 pathToFileURL(mainPath).href : mainPath; 46 return ESMLoader.import(main); 47 }); 48} 49 50// For backwards compatibility, we have to run a bunch of 51// monkey-patchable code that belongs to the CJS loader (exposed by 52// `require('module')`) even when the entry point is ESM. 53function executeUserEntryPoint(main = process.argv[1]) { 54 const resolvedMain = resolveMainPath(main); 55 const useESMLoader = shouldUseESMLoader(resolvedMain); 56 if (useESMLoader) { 57 runMainESM(resolvedMain || main); 58 } else { 59 // Module._load is the monkey-patchable CJS module loader. 60 Module._load(main, null, true); 61 } 62} 63 64module.exports = { 65 executeUserEntryPoint 66}; 67