diff --git a/lib/esm-utils.js b/lib/esm-utils.js index a79aeca74c..2aa9fe674a 100644 --- a/lib/esm-utils.js +++ b/lib/esm-utils.js @@ -30,23 +30,32 @@ const formattedImport = async file => { return import(file); }; -exports.requireOrImport = async file => { - if (path.extname(file) === '.mjs') { - return formattedImport(file); - } - try { - return dealWithExports(await formattedImport(file)); - } catch (err) { - if ( - err.code === 'ERR_MODULE_NOT_FOUND' || - err.code === 'ERR_UNKNOWN_FILE_EXTENSION' - ) { - return require(file); - } else { - throw err; +const hasStableEsmImplementation = (() => { + const [major, minor] = process.version.split('.'); + // ESM is stable from v12.22.0 onward + // https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules + return parseInt(major.slice(1), 10) > 12 || parseInt(minor, 10) >= 22; +})(); + +exports.requireOrImport = hasStableEsmImplementation + ? async file => { + if (path.extname(file) === '.mjs') { + return formattedImport(file); + } + try { + return dealWithExports(await formattedImport(file)); + } catch (err) { + if ( + err.code === 'ERR_MODULE_NOT_FOUND' || + err.code === 'ERR_UNKNOWN_FILE_EXTENSION' + ) { + return require(file); + } else { + throw err; + } + } } - } -}; + : implemenetationOfRequireOrImportForUnstableEsm; function dealWithExports(module) { if (module.default) { @@ -63,3 +72,20 @@ exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => { postLoadFunc(file, result); } }; + +async function implemenetationOfRequireOrImportForUnstableEsm(file) { + if (path.extname(file) === '.mjs') { + return formattedImport(file); + } + // This is currently the only known way of figuring out whether a file is CJS or ESM in + // Node.js that doesn't necessitate calling `import` first. + try { + return require(file); + } catch (err) { + if (err.code === 'ERR_REQUIRE_ESM') { + return formattedImport(file); + } else { + throw err; + } + } +}