如何解决@babel/register转译ESM导入时模块找不到的问题
错误原因
该错误是因为@babel/register默认仅对CommonJS规范的require调用生效,迁移到ESM之后,Node原生ES模块加载器不会触发@babel/register的转译钩子,会直接按导入路径查找.js后缀的物理文件,找不到对应的.tsx源文件,因此抛出模块不存在的报错。
解决方案
方案一:使用@babel/register的ESM加载器(适配现有Babel栈)
- 确认你的
package.json中已经添加"type": "module"配置,开启Node的ESM解析模式。 - 将原有的babel配置抽离到项目根目录的
babel.config.json文件中:
{ "presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ], "extensions": [".tsx"], "cache": false }
- 删除原有代码中手动调用
babelRegister的逻辑,改用Node加载器参数启动项目:
node --loader @babel/register/esm server.js
如果仍有路径解析问题,可以追加实验性参数让Node的模块解析逻辑更贴近CommonJS模式:
node --experimental-specifier-resolution=node --loader @babel/register/esm server.js
方案二:使用tsx运行项目(无需额外配置)
如果不想调整Babel配置,可以直接使用轻量的TS运行时工具tsx,它天然支持ESM规范和TS/TSX文件的路径映射:
- 项目内安装
tsx:
npm install tsx --save-dev
- 直接用
tsx启动项目即可:
npx tsx server.js
注意事项
- 导入路径的大小写需要和物理文件完全匹配,Node的ESM加载器对大小写敏感
- 导入时写的
.js后缀不需要修改,Babel/TS运行时会自动映射到同名的.tsx源文件
内容的提问来源于stack exchange,提问作者sunknudsen
相关产品推荐
相关产品推荐

