Babel/Node:如何混用import/export语法与顶层await
问题描述
我正在启动一个使用react-pdf的Node.js项目,需要通过Babel将TSX语法转译为JS代码,但遇到配置冲突:
- 之前误以为要使用import/export语法,package.json需设置
"type": "commonjs",但顶层await仅支持"type": "module"模式,不清楚二者区别。 - 设置
"type": "commonjs"时,报错:
const token = await getAuthToken(); ^^^^^ SyntaxError: await is only valid in async functions and the top level bodies of modules
- 设置
"type": "module"时,报错:
var _react = _interopRequireDefault(require("react")); ^ ReferenceError: require is not defined in ES module scope, you can use import instead
转译后的文件使用了require()语法,而该语法在ES Module模式下不被允许。需要实现Babel转译为import/export语法,同时支持顶层await特性。
补充配置:
.babelrc文件:
{ "presets": [ [ "@babel/env", { "targets": { "node": 18 } } ], [ "@babel/preset-react", { "targets": { "node": 18 } } ], [ "@babel/preset-typescript", { "targets": { "node": 18 } } ] ], "plugins": [ "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-object-rest-spread" ] }
package.json脚本:
"run": "babel --extensions .ts,.tsx src -d output && node output/document.js"
解决方案
1. 核心区别说明
- CommonJS:Node.js默认模块系统,用
require()加载、module.exports导出,不支持顶层await。 - ES Module:ECMAScript标准模块系统,用
import/export语法,支持顶层await,需在package.json中设置"type": "module"。
2. 修改Babel配置,输出ES Module语法
默认情况下@babel/preset-env会根据目标环境输出CommonJS语法,需显式配置保留原生import/export:
更新.babelrc文件,给@babel/env添加"modules": false选项:
{ "presets": [ [ "@babel/env", { "targets": { "node": 18 }, "modules": false } ], "@babel/preset-react", "@babel/preset-typescript" ], "plugins": [ "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-object-rest-spread" ] }
注:
@babel/preset-react和@babel/preset-typescript无需单独设置targets,会继承@babel/env的配置。
3. 配置package.json为ES Module模式
在package.json中添加:
"type": "module"
4. 验证运行
重新执行脚本:
npm run run
此时Babel会输出使用import/export的ES Module代码,Node在"type": "module"模式下可正常识别语法,同时支持顶层await。
内容的提问来源于stack exchange,提问作者bernardolansing
相关产品推荐
相关产品推荐

