export
Baseline Широко доступен
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в разных версиях браузеров. Она доступна во всех браузерах с мая 2018 года.
Объявление export используется для экспорта значений из JavaScript-модуля. Экспортированные значения затем можно импортировать в другие программы с помощью объявления import или динамического импорта. Значение импортированного привязки может изменяться в модуле, который его экспортирует — когда модуль обновляет значение экспортируемой привязки, это обновление будет видно в импортированном значении.
Чтобы использовать объявление export в файле исходного кода, среда выполнения должна интерпретировать файл как модуль. В HTML это делается путем добавления type="module" к тегу <script>, или путем импорта другим модулем. Модули автоматически интерпретируются в строгом режиме.
Синтаксис
// 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, фактическое экспортируемое имя может быть указано как строковый литерал, который может не являться допустимым идентификатором.
Описание
Каждый модуль может иметь два разных типа экспорта: именованный экспорт и экспорт по умолчанию. Вы можете иметь несколько именованных экспортов на модуль, но только один экспорт по умолчанию. Каждый тип соответствует одному из вышеуказанных синтаксисов.
Именованные экспорты:
// 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 вы можете использовать объявления let, const и var, а также объявления функций или классов. Вы также можете использовать синтаксис export { name1, name2 } для экспорта списка имен, объявленных в другом месте. Обратите внимание, что export {} не экспортирует пустой объект — это объявление-заглушка, которое ничего не экспортирует (пустой список имен).
Вы не можете использовать export для объявления using или await using. Однако вы можете экспортировать переменную, объявленную в другом месте, используя using или await using. Это по-прежнему настоятельно не рекомендуется, поскольку переменная уничтожается сразу после завершения выполнения модуля, и все импортеры получают уже уничтоженное значение.
export using resource1 = getResource(); // SyntaxError
// Allowed by syntax but discouraged
using resource2 = getResource();
export { resource2 };
Экспортные объявления не подлежат правилам временной мертвой зоны. Вы можете объявить, что модуль экспортирует X до того, как само имя X будет объявлено.
export { x };
const x = 1;
// This works, because `export` is only a declaration, but doesn't
// utilize the value of `x`.
Экспорты по умолчанию:
// 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 позволяет использовать любое выражение.
export default 1 + 1;
В качестве особого случая функции и классы экспортируются как объявления, а не выражения, и эти объявления могут быть анонимными. Это означает, что функции будут подняты.
// 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), но экспорт по умолчанию может быть импортирован с любым именем. Например:
// file test.js const k = 12; export default k;
// 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
Вы также можете переименовать именованные экспорты, чтобы избежать конфликтов имен:
export { myFunction as function1, myVariable as variable };
Вы можете переименовать имя во что-то, что не является допустимым идентификатором, используя строковый литерал. Например:
export { myFunction as "my-function" };
Повторный экспорт / Агрегирование
Модуль также может "передавать" значения, экспортируемые из других модулей, без необходимости писать два отдельных оператора import/export. Это часто полезно при создании одного модуля, концентрирующего различные экспорты из разных модулей (обычно называемого "barrel module").
Этого можно достичь с помощью синтаксиса "export from":
export { default as function1, function2 } from "bar.js";
Что сравнимо с комбинацией импорта и экспорта, за исключением того, что function1 и function2 не становятся доступными внутри текущего модуля:
import { default as function1, function2 } from "bar.js";
export { function1, function2 };
Большинство синтаксисов "import from" имеют соответствующие "export from" аналоги.
export { x } from "mod";
export { x as v } from "mod";
export * as ns from "mod";
Существует также export * from "mod", хотя import * from "mod" отсутствует. Это повторно экспортирует все именованные экспорты из mod как именованные экспорты текущего модуля, но экспорт по умолчанию из mod не экспортируется повторно. Если есть два оператора wildcard-экспорта, которые неявно повторно экспортируют одно и то же имя, ни один из них не экспортируется повторно.
// -- 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
Попытка импортировать дублирующееся имя напрямую приведет к ошибке.
import { a } from "./barrel.js";
// SyntaxError: The requested module './barrel.js' contains conflicting star exports for name 'a'
Следующее является синтаксически недействительным, несмотря на его эквивалент импорта:
export DefaultExport from "bar.js"; // Invalid
Примечание: Из-за отсутствия этого синтаксиса import source также не имеет аналога повторного экспорта.
Правильный способ сделать это — переименовать экспорт:
export { default as DefaultExport } from "bar.js";
Синтаксис "export from" позволяет опустить токен as, что позволяет повторно экспортировать экспорт по умолчанию как экспорт по умолчанию.
export { default, function2 } from "bar.js";
export from поддерживает все возможности, которые поддерживает import — например, атрибуты импорта:
export { default } from "./data.json" with { type: "json" };
Примеры
Использование именованных экспортов
В модуле my-module.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-страницу, мы могли бы иметь:
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 с элементом
<script>типаtype="module", чтобы он был распознан как модуль и обработан соответствующим образом. - Вы не можете запускать JS-модули через URL
file://— вы получите ошибки CORS. Вам нужно запускать его через HTTP-сервер.
Использование экспорта по умолчанию
Если мы хотим экспортировать одно значение, представляющее весь модуль, мы можем использовать экспорт по умолчанию:
// module "cube.js"
export default function cube(x) {
return x * x * x;
}
Затем, в другом скрипте, легко импортировать экспорт по умолчанию:
import cube from "./cube.js"; console.log(cube(3)); // 27
Использование export from
Рассмотрим пример с следующей иерархией:
-
childModule1.js: экспортmyFunctionиmyVariable -
childModule2.js: экспортMyClass -
parentModule.js: действует как агрегатор (и ничего больше) - модуль верхнего уровня: потребляет экспорты из
parentModule.js
Вот как это будет выглядеть в виде фрагментов кода:
// In childModule1.js
function myFunction() {
console.log("Hello!");
}
const myVariable = 1;
export { myFunction, myVariable };
// In childModule2.js
class MyClass {
constructor(x) {
this.x = x;
}
}
export { MyClass };
// 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";
// 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® 2027 Language Specification # sec-exports |
Совместимость с браузерами
| Настольные компьютеры | Мобильные устройства | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
export |
61 |
16 |
60 |
48 |
10.1 |
61 |
60 |
45 |
10.3 |
8.0 |
61 |
10.3 |
1.0.0 |
1.0 |
13.2.0Модули должны либо иметь имя файла, заканчивающееся на.mjs, либо ближайший родительский файл package.json должен содержать "type": "module". Дополнительные сведения см. в документации по ECMAScript Modules Node. |
arbitrary_module_namespace_identifier_names |
88 |
88 |
87 |
74 |
14.1 |
88 |
87 |
63 |
14.5 |
15.0 |
88 |
14.5 |
1.0.15 |
1.6 |
16.0.0 |
default |
61 |
16 |
60 |
48 |
10.1 |
61 |
60 |
45 |
10.3 |
8.0 |
61 |
10.3 |
1.0.0 |
1.0 |
13.2.0Модули должны либо иметь имя файла, заканчивающееся на.mjs, либо ближайший родительский файл package.json должен содержать "type": "module". Дополнительные сведения см. в документации по ECMAScript Modules Node. |
namespace |
72 |
79 |
80 |
60 |
14.1 |
72 |
80 |
51 |
14.5 |
11.0 |
72 |
14.5 |
1.0.0 |
1.0 |
13.2.0Модули должны либо иметь имя файла, заканчивающееся на.mjs, либо ближайший родительский файл package.json должен содержать "type": "module". Дополнительные сведения см. в документации по ECMAScript Modules Node. |
См. также
import- Руководство по модулям JavaScript
- ES6 in Depth: Modules на hacks.mozilla.org (2015)
- ES modules: A cartoon deep-dive на hacks.mozilla.org (2018)
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export