SyntaxError: import declarations may only appear at top level of a module
当 import 声明不在模块的顶层时,就会出现 JavaScript 异常“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)
错误类型
哪里出错了?
您可能有一个嵌套在其他结构(例如函数或块)中的 import
声明。import
声明必须位于模块的顶层。如果您想有条件地导入模块,或按需延迟导入它,请改用 动态导入。
如果 import
已经位于代码的顶层,则可能是因为该文件未被解释为模块。运行时需要外部提示来确定文件是否为模块,以下是一些提供此类提示的方法
- 如果文件是从 HTML 直接加载的,请确保
<script>
标签具有type="module"
属性。 - 如果文件在 Node 中运行,请确保该文件具有
.mjs
扩展名,或者最接近的package.json
文件具有"type": "module"
字段。 - 如果文件作为 worker 运行,请确保使用
type: "module"
选项调用Worker()
构造函数。 - 从另一个模块导入此文件。
另一个原因可能是当您使用编译器(如 TypeScript)编写 import
并意外运行源文件时。由于 import
声明通常出现在程序的开头,因此解析器首先看到它们,然后抱怨。请确保编译源文件并执行编译后的文件。
示例
条件导入
您不能在其他结构中使用 import
,就像您在 Python 中可能做的那样。
js
if (writeOutput) {
import fs from "fs"; // SyntaxError
}
将 import
移动到顶层,或使用动态导入。
js
if (writeOutput) {
import("fs").then((fs) => {
// use fs
});
}
在非模块脚本中导入
如果您从 HTML 加载脚本,请确保向 <script>
标签添加 type="module"
属性。
html
<script type="module" src="main.js"></script>
如果由于某种原因您无法将脚本迁移到模块,则可以使用动态导入。
js
async function main() {
const myModule = await import("./my-module.js");
// use myModule
}
main();