在ExpressJS中结合Webpack和Babel使用import替代require的正确方法
解决Node运行ES模块import报错的问题
我太懂这种头疼的情况了——babel-node能正常跑但直接用node就报unexpected token import,而且生产环境还不能依赖babel-node,毕竟它是实时转译,性能拉胯还没法缓存,完全不适合生产场景。下面给你一套靠谱的解决方案:
核心原因
babel-node会在运行时实时把ES6+的import语法转译成Node支持的CommonJS(也就是require)语法,但直接用node执行源码的话,Node默认不认识未转译的import(除非你用的是非常新的Node版本且配置了ES模块模式,但生产环境通常需要兼容更多场景)。所以我们的核心思路是:先提前把源码转译成Node能识别的代码,再运行转译后的文件。
具体步骤
1. 安装必要的Babel依赖
首先确保你已经安装了正确的Babel工具,用yarn安装这些开发依赖(生产环境不需要它们,只需要转译后的代码):
yarn add --dev @babel/core @babel/cli @babel/preset-env
@babel/core:Babel的核心转译引擎@babel/cli:命令行工具,用来批量转译文件@babel/preset-env:根据目标环境自动转译对应语法的预设,就是你现在用的这个
2. 配置Babel转译规则
在项目根目录创建babel.config.json文件(或者用.babelrc,前者更推荐用于现代Babel版本),写入以下配置:
{ "presets": [ [ "@babel/preset-env", { "targets": { "node": "current" // 转译到当前你使用的Node版本,也可以指定具体版本比如"16" } } ] ] }
这个配置会告诉Babel,根据你指定的Node版本,只转译该版本不支持的语法,尽可能保留原生支持的特性,提升性能。
3. 添加package.json脚本
打开你的package.json,添加两个脚本:
{ "scripts": { "build": "babel src --out-dir dist", // 把src目录下的源码转译到dist目录 "start": "node dist/index.js" // 运行转译后的入口文件(这里假设你的入口是src/index.js) } }
yarn build:执行转译,会把src里的所有文件转译后放到dist目录yarn start:运行转译后的代码,这时候Node就能正常识别了
4. 测试运行
先执行转译:
yarn build
然后运行转译后的代码:
yarn start
这样就不会再出现unexpected token import的错误了。
可选方案:直接使用Node原生ES模块
如果你的Node版本足够新(比如Node 14+),也可以不用Babel转译,直接开启ES模块模式:
- 在
package.json里添加"type": "module" - 确保你的文件扩展名是
.js(或者.mjs),这时候Node会把文件当作ES模块处理,支持import语法 - 注意:这种情况下,所有依赖也需要支持ES模块,而且如果要兼容旧版Node的话,这个方案就不适用了
内容的提问来源于stack exchange,提问作者Matt Hough
相关产品推荐
相关产品推荐

