Repository navigation
Cannot import ESM modules when modifying require.extensions #4350
Description
TL;DR
How to require (or import) Native ESM modules while using a require hook like require.extensions.
Note: I do know that
require.extensionsis deprecated and is not recommended to modify, but asts-nodedoes, I am using this as a part of a temporary workaround.
Goal
I want to dynamic import a configuration file, jiwon.config.ts, which should import other JS/TS extensions successfully.
Restrictions
I cannot use other dependencies like webpack or esbuild to bundle and resolve the imports.
The only option is to use SWC.
Work Flow
importConfig()- looks for
jiwon.config.ts, exists - REGISTER REQUIRE HOOK
readFile()the config- SWC
transformthe code writeFile()the config as.js- dynamic import
jiwon.config.js
REGISTER REQUIRE HOOK
Why? To not bundle and do fewer operations on resolving the config file. Especially utilizing the high performance of SWC.
import { transformSync, type Options } from '@swc/core'
const originalJsHandler = require.extensions['.js']
const transformableExtensions = ['.ts', '.cts', '.mts', '.cjs', '.mjs']
const swcOptions: Options = {
jsc: {
target: 'es5',
parser: {
syntax: 'typescript',
},
},
module: {
type: 'commonjs',
},
isModule: 'unknown',
}
function registerSWCTransform(swcOptions: Options, isESM: boolean) {
// if (isESM) {
// TODO: handle ESM
// }
for (const ext of transformableExtensions) {
require.extensions[ext] = function (m: any, originalFileName) {
const _compile = m._compile
m._compile = function (code: string, filename: string) {
const swc = transformSync(code, swcOptions)
return _compile.call(this, swc.code, filename)
}
return originalJsHandler(m, originalFileName)
}
}
}Current Status
By doing so, I've achieved to cover 90% of the expected & edge cases of resolving the config file.
The only thing that I am struggling with is:
- On the Native ESM project (package.json type: module), import the
.js(ESM) file. - On the CJS project, import the Native ESM package(also,
.js).
They both have in common that the format is ESM but the extension is .js.
As I tried to overwrite the require.extensions['.js'], threw an error during the process of importing other .js files.
Requesting for Help
If you...
- know how to resolve requiring Native ESM
.jsfile with the current status - can suggest other ways to achieve the current goal than to register the require hook
please share your expertise and insights, will be very grateful for your help.
Node.js version
{
node: '18.17.0',
acorn: '8.8.2',
ada: '2.5.0',
ares: '1.19.1',
brotli: '1.0.9',
cldr: '43.0',
icu: '73.1',
llhttp: '6.0.11',
modules: '108',
napi: '9',
nghttp2: '1.52.0',
nghttp3: '0.7.0',
ngtcp2: '0.8.1',
openssl: '3.0.9+quic',
simdutf: '3.2.12',
tz: '2023c',
undici: '5.22.1',
unicode: '15.0',
uv: '1.44.2',
uvwasi: '0.0.18',
v8: '10.2.154.26-node.26',
zlib: '1.2.13.1-motley'
}Example code
See above.
Operating system
Darwin MacBook-Pro.local 23.1.0 Darwin Kernel Version 23.1.0: Mon Oct 9 21:32:11 PDT 2023; root:xnu-10002.41.9~7/RELEASE_ARM64_T6030 arm64Scope
Custom compiling through modifying require.extensions.
Module and version
Not applicable.
Activity
github-actions commentedon Dec 8, 2024
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.
github-actions commentedon Jan 8, 2025
It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.