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();

另見