ES Module 导入错误:SyntaxError: Cannot use import statement outside a module
问题描述
在 Node.js 环境中尝试使用 ES Module 的 import
语法导入模块时,开发者经常会遇到以下错误:
SyntaxError: Cannot use import statement outside a module
这个错误通常发生在以下场景中:
- 在 Node.js 中尝试使用
import
语句但未正确配置 - 在浏览器中使用 ES Module 但未正确声明脚本类型
- 文件扩展名或项目配置不正确
示例代码:
// main.js
import * as myModule from "mod";
myModule.func();
// mod.js
export function func(){
console.log("Hello World");
}
解决方案
方法一:配置 package.json 启用 ES Module
在项目的 package.json 文件中添加 "type": "module"
字段:
{
"name": "your-project",
"version": "1.0.0",
"type": "module",
// 其他配置...
}
TIP
此配置会使项目中的所有 .js 文件被当作 ES Module 处理,此时你可以正常使用 import/export
语法。
方法二:修改文件扩展名
将你的 JavaScript 文件扩展名从 .js
改为 .mjs
(Module JavaScript):
# 重命名文件
mv main.js main.mjs
mv mod.js mod.mjs
# 运行程序
node main.mjs
WARNING
使用 .mjs
扩展名时,Node.js 会自动将其识别为 ES Module,无需修改 package.json 配置。
方法三:使用命令行标志(旧版本 Node.js)
对于 Node.js 13 之前的版本,需要使用 --experimental-modules
标志:
node --experimental-modules main.js
DANGER
此方法已过时,建议升级 Node.js 版本并使用前两种方法。Node.js 13.2.0 及以上版本已稳定支持 ES Module。
方法四:浏览器环境中的解决方案
在 HTML 文件中使用模块时,需要在 script 标签中添加 type="module"
属性:
<script src="main.js" type="module"></script>
方法五:回退到 CommonJS 语法
如果不想使用 ES Module,可以改用 Node.js 传统的 CommonJS 模块系统:
// mod.js
module.exports.func = function (){
console.log("Hello World");
}
// main.js
const myMod = require("./mod");
myMod.func();
TypeScript 项目的特殊处理
对于 TypeScript 项目,需要使用 TypeScript 编译器先编译文件:
# 编译 TypeScript 文件
npx tsc file.ts
# 运行生成的 JavaScript 文件
node file.js
或者在 package.json 中配置测试脚本时使用 cross-env:
{
"scripts": {
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\" }' mocha -r ts-node/register -r src/**/*.spec.ts"
}
}
总结
解决 "Cannot use import statement outside a module" 错误的主要方法有:
- 在 package.json 中设置
"type": "module"
- 使用
.mjs
扩展名替代.js
- 浏览器环境中添加
type="module"
属性 - 回退到 CommonJS 的
require/module.exports
语法
INFO
自 Node.js 13.2.0 起,ES Module 支持已稳定,无需使用实验性标志。建议始终使用最新的 Node.js LTS 版本以获得最佳兼容性。
选择哪种方法取决于你的项目需求和环境。对于新项目,推荐使用 ES Module 并配置 "type": "module"
,这是现代 JavaScript 的标准模块系统。