语法错误:import 声明只能出现在模块的顶层
当导入声明不在模块的顶层时,会发生 JavaScript 异常 "import 声明只能出现在模块的顶层"。这可能是因为导入声明嵌套在其他构造(函数、块等)中,或者更常见的情况是当前文件未被视为模块。
¥The JavaScript exception "import declarations may only appear at top level of a module" occurs when an import declaration is not at the top level of a module. This might be because the import declaration is nested in other constructs (functions, blocks, etc.), or more often because the current file is not treated as a module.
信息
错误类型
什么地方出了错?
¥What went wrong?
你可能有一个嵌套在另一个构造(例如函数或块)中的 import
声明。import
声明必须位于模块的顶层。如果你想有条件地导入模块,或根据需要延迟导入,请改用 动态导入。
¥You may have an import
declaration that's nested in another construct, such as a function or a block. The import
declaration must be at the top level of the module. If you want to conditionally import a module, or lazily import it on demand, use dynamic import instead.
如果 import
已经位于代码的顶层,可能是因为该文件未被解释为模块。运行时需要外部提示来确定文件是否为模块,以下是提供此类提示的几种方法:
¥If the import
is already at the top level of the code, it may be because the file is not interpreted as a module. Runtimes require external hints to determine whether a file is a module or not, and here are several ways to provide such hints:
- 如果文件直接从 HTML 加载,请确保
<script>
标记具有type="module"
属性。 - 如果文件在 Node 中运行,请确保文件具有
.mjs
扩展名,或者最近的package.json
文件具有"type": "module"
字段。 - 如果文件作为 worker 运行,请确保使用
type: "module"
选项调用Worker()
构造函数。 - 从另一个模块导入此文件。
另一个原因可能是当你使用编译器(例如 TypeScript)编写 import
时,你意外运行了源文件。由于 import
声明通常出现在程序的最开始,因此它们是解析器看到的第一件事,然后会抱怨。确保编译源文件并执行编译后的文件。
¥One other cause might be when you are writing import
with a compiler (such as TypeScript) and you accidentally ran the source file. Since import
declarations usually appear at the very start of the program, they are the first thing the parser sees and then complains about. Make sure to compile the source file and execute the compiled file instead.
示例
条件导入
¥Conditional imports
你不能在其他构造中使用 import
,就像在 Python 中一样。
¥You cannot use import
inside other constructs, like you might do in Python.
if (writeOutput) {
import fs from "fs"; // SyntaxError
}
将 import
移至顶层,或使用动态导入。
¥Either move the import
to the top level, or use dynamic import.
if (writeOutput) {
import("fs").then((fs) => {
// use fs
});
}
在非模块脚本中导入
¥Importing in a non-module script
如果你从 HTML 加载脚本,请确保将 type="module"
属性添加到 <script>
标记。
¥If you are loading the script from HTML, make sure to add the type="module"
attribute to the <script>
tag.
<script type="module" src="main.js"></script>
如果由于某种原因你无法将脚本迁移到模块,则可以使用动态导入。
¥If for some reason you cannot migrate the script to a module, you can use dynamic import.
async function main() {
const myModule = await import("./my-module.js");
// use myModule
}
main();