Description
Every module can have two different types of export, named export and default export. You can have multiple named exports per module but only one default export. Each type corresponds to one of the above syntax.
Named exports:
// 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() { /* ... */ };
After the export
keyword, you can use let
, const
, and var
declarations, as well as function or class declarations. You can also use the export { name1, name2 }
syntax to export a list of names declared elsewhere. Note that export {}
does not export an empty object - it's a no-op declaration that exports nothing (an empty name list).
Export declarations are not subject to temporal dead zone rules. You can declare that the module exports X
before the name X
itself is declared.
export { x }; const x = 1; // This works, because `export` is only a declaration, but doesn't // utilize the value of `x`.
Default exports:
// 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 { /* … */ } // each export overwrites the previous one
The export default
syntax allows any expression.
export default 1 + 1;
As a special case, functions and classes are exported as declarations, not expressions, and these declarations can be anonymous. This means functions will be hoisted.
// 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"); }
Named exports are useful when you need to export several values. When
importing this module, named exports must be referred to by the exact
same name (optionally renaming it with as
), but the default export can be imported with any name. For example:
// 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); // will log 12
You can also rename named exports to avoid naming conflicts:
export { myFunction as function1, myVariable as variable, };
You can rename a name to something that's not a valid identifier by using a string literal. For example:
export { myFunction as "my-function" };
Re-exporting / Aggregating
A module can also "relay" values exported from other modules without the hassle of writing two separate import/export statements. This is often useful when creating a single module concentrating various exports from various modules (usually called a "barrel module").
This can be achieved with the "export from" syntax:
export { default as function1, function2, } from 'bar.js';
Which is comparable to a combination of import and export, except that function1
and function2
do not become available inside the current module:
import { default as function1, function2 } from 'bar.js';
export { function1, function2 };
Most of the "import from" syntaxes have "export from" counterparts.
export { x } from "mod"; export { x as v } from "mod"; export * as ns from "mod";
There is also export * from "mod"
, although there's no import * from "mod"
. This re-exports all named exports from mod
as the named exports of the current module, but the default export of mod
is not re-exported. If there are two wildcard exports statements that
implicitly re-export the same name, neither one is re-exported.
// -- 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
Attempting to import the duplicate name directly will throw an error.
import { a } from "./barrel.js"; // SyntaxError: The requested module './barrel.js' contains conflicting star exports for name 'a'
The following is syntactically invalid despite its import equivalent:
export DefaultExport from 'bar.js'; // Invalid
The correct way of doing this is to rename the export:
export { default as DefaultExport } from 'bar.js';
The "export from" syntax allows the as
token to be omitted, which makes the default export still re-exported as default export.
export { default, function2 } from 'bar.js';