export

Baseline 已廣泛支援

此功能已成熟,並可在許多裝置和瀏覽器版本上執行。自 2018 年 5 月起,它已在各個瀏覽器中可用。

export 宣告用於從 JavaScript 模組中匯出值。匯出的值可以透過 import 宣告或動態匯入匯入到其他程式中。匯入繫結的值可能會在匯出它的模組中發生變化——當一個模組更新它匯出的繫結值時,這個更新將在其匯入的值中可見。

為了在原始檔中使用 export 宣告,執行時必須將該檔案解釋為模組。在 HTML 中,這可以透過在 <script> 標籤中新增 type="module",或者被另一個模組匯入來實現。模組會自動以嚴格模式解釋。

語法

js
// Exporting declarations
export let name1, name2/*, … */; // also var
export const name1 = 1, name2 = 2/*, … */; // also var, let
export function functionName() { /* … */ }
export class ClassName { /* … */ }
export function* generatorFunctionName() { /* … */ }
export const { name1, name2: bar } = o;
export const [ name1, name2 ] = array;

// Export list
export { name1, /* …, */ nameN };
export { variable1 as name1, variable2 as name2, /* …, */ nameN };
export { variable1 as "string name" };
export { name1 as default /*, … */ };

// Default exports
export default expression;
export default function functionName() { /* … */ }
export default class ClassName { /* … */ }
export default function* generatorFunctionName() { /* … */ }
export default function () { /* … */ }
export default class { /* … */ }
export default function* () { /* … */ }

// Aggregating modules
export * from "module-name";
export * as name1 from "module-name";
export { name1, /* …, */ nameN } from "module-name";
export { import1 as name1, import2 as name2, /* …, */ nameN } from "module-name";
export { default, /* …, */ } from "module-name";
export { default as name1 } from "module-name";
nameN

要匯出的識別符號(以便可以透過另一個指令碼中的import匯入)。如果使用帶 as 的別名,實際匯出的名稱可以指定為字串字面量,這可能不是一個有效的識別符號。

描述

每個模組可以有兩種不同型別的匯出:命名匯出預設匯出。每個模組可以有多個命名匯出,但只能有一個預設匯出。每種型別對應上述語法之一。

命名匯出

js
// export features declared elsewhere
export { myFunction2, myVariable2 };

// export individual features (can export var, let,
// const, function, class)
export let myVariable = Math.sqrt(2);
export function myFunction() {
  // …
}

export 關鍵字之後,可以使用 letconstvar 宣告,以及函式或類宣告。還可以使用 export { name1, name2 } 語法匯出在其他地方宣告的名稱列表。請注意,export {} 不會匯出一個空物件——它是一個不執行任何操作的宣告,不匯出任何東西(一個空的名稱列表)。

你不能在 usingawait using 宣告上使用 export。但是,你可以匯出已使用 usingawait using 在其他地方宣告的變數。這樣做仍然強烈不建議,因為變數一旦模組執行完畢就會被釋放,導致所有匯入者接收到一個已經釋放的值。

js
export using resource1 = getResource(); // SyntaxError

// Allowed by syntax but discouraged
using resource2 = getResource();
export { resource2 };

匯出宣告不受暫時性死區規則的限制。你可以在名稱 X 本身被宣告之前宣告模組匯出 X

js
export { x };
const x = 1;
// This works, because `export` is only a declaration, but doesn't
// utilize the value of `x`.

預設匯出

js
// export feature declared elsewhere as default
export { myFunction as default };
// This is equivalent to:
export default myFunction;

// export individual features as default
export default function () { /* … */ }
export default class { /* … */ }

注意:匯出宣告的名稱必須彼此不同。如果存在名稱重複的匯出或使用多個 default 匯出,將導致 SyntaxError 並阻止模組被評估。

export default 語法允許任何表示式。

js
export default 1 + 1;

作為特例,函式和類作為*宣告*而不是表示式匯出,並且這些宣告可以是匿名的。這意味著函式會被提升。

js
// Works because `foo` is a function declaration,
// not a function expression
foo();

export default function foo() {
  console.log("Hi");
}

// It's still technically a declaration, but it's allowed
// to be anonymous
export default function () {
  console.log("Hi");
}

命名匯出在需要匯出多個值時很有用。匯入此模組時,命名匯出必須以完全相同的名稱引用(可以選擇使用 as 重新命名),但預設匯出可以以任何名稱匯入。例如

js
// file test.js
const k = 12;
export default k;
js
// some other file
import m from "./test"; // note that we have the freedom to use import m instead of import k, because k was default export

console.log(m); // 12

你也可以重新命名命名匯出以避免命名衝突

js
export { myFunction as function1, myVariable as variable };

你可以使用字串字面量將名稱重新命名為不是有效識別符號的內容。例如

js
export { myFunction as "my-function" };

重新匯出 / 聚合

一個模組還可以“中繼”從其他模組匯出的值,而無需編寫兩個單獨的 import/export 語句的麻煩。這通常在建立集中了各種模組的各種匯出的單個模組(通常稱為“桶模組”)時很有用。

這可以透過“export from”語法實現

js
export { default as function1, function2 } from "bar.js";

這類似於 import 和 export 的組合,不同之處在於 function1function2 在當前模組內部不可用

js
import { default as function1, function2 } from "bar.js";

export { function1, function2 };

大多數“import from”語法都有“export from”對應的語法。

js
export { x } from "mod";
export { x as v } from "mod";
export * as ns from "mod";

還有 export * from "mod",儘管沒有 import * from "mod"。它將 mod 的所有命名匯出重新匯出為當前模組的命名匯出,但 mod 的預設匯出不被重新匯出。如果存在兩個萬用字元匯出語句隱式地重新匯出相同的名稱,則兩者都不會被重新匯出。

js
// -- mod1.js --
export const a = 1;

// -- mod2.js --
export const a = 3;

// -- barrel.js --
export * from "./mod1.js";
export * from "./mod2.js";

// -- main.js --
import * as ns from "./barrel.js";

console.log(ns.a); // undefined

嘗試直接匯入重複的名稱將丟擲錯誤。

js
import { a } from "./barrel.js";
// SyntaxError: The requested module './barrel.js' contains conflicting star exports for name 'a'

儘管有其匯入等價物,但以下語法是無效的

js
export DefaultExport from "bar.js"; // Invalid

正確的做法是重新命名匯出

js
export { default as DefaultExport } from "bar.js";

“export from”語法允許省略 as 標記,這使得預設匯出仍作為預設匯出重新匯出。

js
export { default, function2 } from "bar.js";

export from 支援 import 支援的所有功能——例如,匯入屬性

js
export { default } from "./data.json" with { type: "json" };

示例

使用命名匯出

在模組 my-module.js 中,我們可以包含以下程式碼

js
// module "my-module.js"
function cube(x) {
  return x * x * x;
}

const foo = Math.PI + Math.SQRT2;

const graph = {
  options: {
    color: "white",
    thickness: "2px",
  },
  draw() {
    console.log("From graph draw function");
  },
};

export { cube, foo, graph };

然後,在你的 HTML 頁面中包含的頂級模組中,我們可以有

js
import { cube, foo, graph } from "./my-module.js";

graph.options = {
  color: "blue",
  thickness: "3px",
};

graph.draw(); // Logs "From graph draw function"
console.log(cube(3)); // 27
console.log(foo); // 4.555806215962888

以下幾點需要注意

  • 你需要將此指令碼包含在你的 HTML 中,使用 type="module"<script> 元素,以便它被識別為模組並得到適當處理。
  • 你不能透過 file:// URL 執行 JS 模組——你會遇到 CORS 錯誤。你需要透過 HTTP 伺服器執行它。

使用預設匯出

如果我們要匯出代表整個模組的單個值,我們可以使用預設匯出

js
// module "cube.js"

export default function cube(x) {
  return x * x * x;
}

然後,在另一個指令碼中,匯入預設匯出非常簡單

js
import cube from "./cube.js";

console.log(cube(3)); // 27

使用 export from

讓我們舉一個例子,我們有以下層次結構

  • childModule1.js: 匯出 myFunctionmyVariable
  • childModule2.js: 匯出 MyClass
  • parentModule.js: 作為聚合器(不執行其他操作)
  • 頂級模組:消費 parentModule.js 的匯出

程式碼片段如下所示

js
// In childModule1.js
function myFunction() {
  console.log("Hello!");
}
const myVariable = 1;
export { myFunction, myVariable };
js
// In childModule2.js
class MyClass {
  constructor(x) {
    this.x = x;
  }
}

export { MyClass };
js
// In parentModule.js
// Only aggregating the exports from childModule1 and childModule2
// to re-export them
export { myFunction, myVariable } from "childModule1.js";
export { MyClass } from "childModule2.js";
js
// In top-level module
// We can consume the exports from a single module since parentModule
// "collected"/"bundled" them in a single source
import { myFunction, myVariable, MyClass } from "parentModule.js";

規範

規範
ECMAScript® 2026 語言規範
# sec-exports

瀏覽器相容性

另見