语法错误: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.

信息

¥Message

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)

错误类型

¥Error type

SyntaxError

什么地方出了错?

¥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.

示例

¥Examples

条件导入

¥Conditional imports

你不能在其他构造中使用 import,就像在 Python 中一样。

¥You cannot use import inside other constructs, like you might do in Python.

js
if (writeOutput) {
  import fs from "fs"; // SyntaxError
}

import 移至顶层,或使用动态导入。

¥Either move the import to the top level, or use dynamic import.

js
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.

html
<script type="module" src="main.js"></script>

如果由于某种原因你无法将脚本迁移到模块,则可以使用动态导入。

¥If for some reason you cannot migrate the script to a module, you can use dynamic import.

js
async function main() {
  const myModule = await import("./my-module.js");
  // use myModule
}

main();

也可以看看