SyntaxError: import declarations may only appear at top level of a module
JavaScript 异常 "import declarations may only appear at top level of a module"(import 声明只能出现在模块的顶层)发生在 import 声明没有出现在模块的顶层时。这可能是因为 import 声明嵌套在其他结构(函数、块等)中,或者更常见的是因为当前文件没有被当作模块处理。
消息
SyntaxError: Cannot use import statement outside a module (V8-based) SyntaxError: import declarations may only appear at top level of a module (Firefox) SyntaxError: Unexpected identifier 'x'. import call expects one or two arguments. (Safari)
错误类型
SyntaxError
哪里出错了?
你可能有一个嵌套在其他结构(例如函数或块)中的 import 声明。import 声明必须位于模块的顶层。如果你想有条件地导入模块,或者按需延迟导入模块,请改用动态 import。
如果 import 已经位于代码的顶层,那可能是因为文件未被解释为模块。运行时需要外部提示来确定文件是否为模块,以下是提供此类提示的几种方法:
- 如果文件直接从 HTML 加载,请确保
<script>标签具有type="module"属性。 - 如果文件在 Node 中运行,请确保文件具有
.mjs扩展名,或者最近的package.json文件具有"type": "module"字段。 - 如果文件作为 worker 运行,请确保在调用
Worker()构造函数时带有type: "module"选项。 - 从另一个模块导入此文件。
另一个原因可能是当你使用编译器(如 TypeScript)编写 import 时,你不小心运行了源文件。由于 import 声明通常出现在程序的开头,它们是解析器首先看到并抱怨的东西。请确保编译源文件并执行编译后的文件。
示例
条件导入
你不能像在 Python 中那样在其他结构内部使用 import。
js
if (writeOutput) {
import fs from "fs"; // SyntaxError
}
要么将 import 移动到顶层,要么使用动态 import。
js
if (writeOutput) {
import("fs").then((fs) => {
// use fs
});
}
在非模块脚本中导入
如果你从 HTML 加载脚本,请务必将 type="module" 属性添加到 <script> 标签。
html
<script type="module" src="main.js"></script>
如果由于某种原因你无法将脚本迁移到模块,则可以使用动态 import。
js
async function main() {
const myModule = await import("./my-module.js");
// use myModule
}
main();