Node.js生产环境运行报错:import语句无法在模块外使用的解决咨询
如何解决Node.js项目生产版本运行时的ES模块语法错误?
看起来你遇到的问题核心是代码混合了CommonJS(require)和ES模块(import)语法,直接用node命令运行时没有转译这些语法,导致报错。咱们一步步来解决:
先搞懂为什么nodemon能正常运行
你的start脚本用了babel-node,它会在运行时自动把ES模块的import语法转译成Node.js原生支持的CommonJS语法,所以nodemon能正常跑起来;但直接用node src/index.js时,没有经过这个转译步骤,Node.js就会抛出SyntaxError: Cannot use import statement outside a module的错误。
方案一:用Babel编译代码后再运行(推荐用于生产环境)
babel-node主要是开发时的工具,生产环境性能不够好,所以我们先把代码编译成Node.js能直接运行的版本,再启动:
- 确保你安装了
@babel/cli(如果没有,执行npm install --save-dev @babel/cli) - 在项目根目录创建
.babelrc配置文件,内容如下:
{ "presets": ["@babel/preset-env"] }
- 修改
package.json里的scripts,添加编译命令并更新生产启动命令:
"scripts": { "start": "nodemon --exec babel-node src/index.js", "build": "babel src --out-dir dist", "production": "NODE_ENV=production node dist/index.js", "win-prod": "set NODE_ENV=production && node dist/index.js", "test": "echo \"No test specified\" && exit 0" }
- 执行编译命令,把
src目录的代码转译到dist目录:
npm run build
- 最后运行生产版本:
- Windows系统:
npm run win-prod - Mac/Linux系统:
npm run production
方案二:统一代码为纯ES模块语法
如果你不想用Babel转译,也可以调整代码让Node.js直接识别为ES模块:
- 在
package.json里添加"type": "module",修改后的配置片段:
{ "name": "node-express-server-rest-api", "version": "0.1.0", "type": "module", // 其他原有配置... }
- 把代码里所有的
require替换成import语法:
原来的代码:
require('dotenv/config'); const bodyParser = require("body-parser");
改成:
import 'dotenv/config'; import bodyParser from "body-parser";
- 现在可以直接运行生产命令了:
- Windows:
npm run win-prod - 其他系统:
npm run production
为什么之前加type:module会出问题?
当你设置"type": "module"后,Node.js会把所有.js文件当作ES模块处理,这时候使用CommonJS的require语法就会报错,所以必须把所有require都改成import才能正常运行。
内容的提问来源于stack exchange,提问作者Bright Chip
相关产品推荐
相关产品推荐

