"use strict"; const babelCore = require("@babel/core"); const Module = require("module").Module; const fs = require("fs"); function transpile(code) { return babelCore.transformSync(code, { plugins: [ require.resolve("@babel/plugin-proposal-export-namespace-from"), require.resolve("@babel/plugin-transform-modules-commonjs"), require.resolve("@babel/plugin-transform-runtime"), require.resolve("babel-plugin-transform-import-meta") ] }); } let oldJSLoader, oldMJSLoader; module.exports = { register: function () { // NOTE: We only capture these at register time, to ensure that we don't interfere with any other custom require hooks oldJSLoader = Module._extensions[".js"]; oldMJSLoader = Module._extensions[".mjs"]; let newLoader = function (mod, filename) { try { return oldJSLoader(mod, filename); } catch (error) { if (error.code === "ERR_REQUIRE_ESM") { // NOTE: We completely bypass the default internal loader, as we cannot patch the `type: module` check out of that. Please open a PR if you have a better solution! let code = fs.readFileSync(filename, "utf8"); let transpiledCode = transpile(code); mod._compile(transpiledCode.code, filename); } else { throw error; } } } Module._extensions[".js"] = newLoader; Module._extensions[".mjs"] = newLoader; }, unregister: function () { Module._extensions[".js"] = oldJSLoader; Module._extensions[".mjs"] = oldMJSLoader; }, require: function (... args) { this.register(); let required = require(... args); this.unregister(); return required; } };