Node.js运行服务时无法使用import语法报Unexpected token {错误
import { start } from './server';
^
SyntaxError: Unexpected token {
at Module._compile (internal/modules/cjs/loader.js:723:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
报错诱因
Node.js 默认使用CommonJS模块规范(对应require/module.exports语法),仅对符合ES模块规范的文件才支持import/export语法,触发该报错的核心原因是当前Node.js进程将你运行的入口文件识别为了CommonJS模块,无法识别ES模块的import语法。
常见触发场景包括:
- Node.js版本低于13.2.0,该版本才开始正式稳定支持ES模块,更低版本默认未开启对应能力
- 项目根目录的
package.json中没有设置"type": "module"字段,Node.js会默认将所有.js后缀的文件识别为CommonJS模块 - 运行文件的后缀为
.cjs,该后缀强制被识别为CommonJS模块,不支持使用import语法 - 此前使用
import的项目配置了Babel、ts-node等转译工具,或是本身已经配置了ES模块识别规则,本次运行的项目缺少对应配置
可行解决方案
方案1:配置项目为ES模块规范(推荐,适配新标准)
在项目根目录的package.json文件中添加"type": "module"字段,Node.js会将所有.js后缀文件识别为ES模块,原生支持import语法。
注意该配置下默认不能使用CommonJS的require语法,如果有混用需求,可以将需要使用CommonJS规范的文件后缀改为.cjs。
方案2:使用转译工具兼容
- 安装Babel对代码进行转译,配置
@babel/preset-env预设,将ES模块语法转为CommonJS语法后再运行 - 开发环境也可以使用
esm模块作为加载器,将运行命令改为node -r esm 你的入口文件路径,无需修改现有代码即可支持import语法
方案3:更换为CommonJS语法
如果不想调整项目配置,可以直接将import语句替换为CommonJS的require写法:
将import { start } from './server'改为const { start } = require('./server'),同时对应server.js文件中的export语句也要改为module.exports的写法。
方案4:修改文件后缀
如果不想修改package.json配置,直接将入口文件和所有使用了ES模块语法的.js文件后缀改为.mjs,Node.js会自动识别.mjs文件为ES模块,支持import语法。
内容的提问来源于stack exchange,提问作者Nadin Gomaa

