export

export 文は JavaScript モジュールを作成する際に使用され、モジュールから関数、オブジェクト、またはプリミティブ値への生きたバインディングをエクスポートして、 import 文を使用した他のプログラムで使用できるようにします。エクスポートされたバインディングは、ローカルで変更することができます。インポートされた場合、これらはインポートしたモジュールからしか読み取ることができませんが、値はモジュールをエクスポートするたびにこうして更新するたびに更新されます。

エクスポートされたモジュールは、宣言のあるなしにかかわらず厳格モードで動作します。 export 文は、埋め込みスクリプトでは使えません。

構文

2種類のエクスポート方法があります。

  1. 名前付きエクスポート (モジュール当たり0個以上のエクスポート)
  2. 既定のエクスポート (モジュール当たり1個のエクスポート)
// 個々の機能のエクスポート
export let name1, name2, …, nameN; // var, const も
export let name1 = …, name2 = …, …, nameN; // var, const も
export function functionName(){...}
export class ClassName {...}

// エクスポートリスト
export { name1, name2, …, nameN };

// エクスポート時の名前変更
export { variable1 as name1, variable2 as name2, …, nameN };

// Exporting destructured assignments with renaming
export const { name1, name2: bar } = o;

// 既定のエクスポート
export default expression;
export default function (…) { … } // class, function* も使用可
export default function name1(…) { … } // class, function* も使用可
export { name1 as default, … };

// モジュールのアグリゲート
export * from …; // does not set the default export
export * as name1 from …; // Draft ECMAScript® 2O21
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;
nameN
(別のスクリプトで import を使用してインポートできるようにするため) エクスポートする識別子です。

解説

エクスポート方法は、名前付きデフォルトの 2 種類あります。名前付きエクスポートはモジュールごとに複数持てますが、デフォルトエクスポートは 1 つに限ります。それぞれのエクスポート方法は、上記の構文のひとつに対応します。

名前付きエクスポート:

// 事前に宣言された機能のエクスポート
export { myFunction, myVariable }; 

// 個別の機能のエクスポート (var, let,
// const, function, class がエクスポート可能)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };

デフォルトエクスポート:

// デフォルトとして事前に定義された機能のエクスポート
export { myFunction as default };

// 個別の機能をデフォルトとしてエクスポート
export default function () { ... } 
export default class { .. }

名前付きエクスポートは、さまざまな値をエクスポートするのに役立ちます。インポートするときは、対応するオブジェクトと同じ名前を使用しなければなりません。

一方、デフォルトエクスポートは以下のように任意の名前を使用できます。

// ファイル test.js
let k; export default k = 12;
// 他のファイル
import m from './test'; // k がデフォルトエクスポートなので、インポートする k の代わりに m を使用することができる点に注意してください
console.log(m);        // log 12 になる

名前の競合を防ぐために、名前付きエクスポートの名前を変更することもできます。

export { myFunction as function1,
         myVariable as variable };

再エクスポート / アグリゲート

また、親モジュール内の異なるモジュールから「インポート/エクスポート」して、そのモジュールからインポートできるようにすることも可能です。つまり export foo from 'bar.js' を使って、様々なモジュールからの様々なエクスポートを集約した1つのモジュールを作ることができます。

この構文、

export foo from 'bar.js';

は、次のものと等価です。

import foo from 'bar.js';
export foo;

以下の階層構造で例を見てみましょう。

  • childModule1.js: myFunction および myVariable をエクスポート
  • childModule2.js: myClass をエクスポート
  • parentModule.js: アグリゲーターとして動作する (そして他には何もしない)
  • 最上位モジュール: parentModule.js のエクスポートを消費

コードスニペットを使うとこのような感じになります。

// In childModule1.js
let myFunction = ...; // assign something useful to myFunction
let myVariable = ...; // assign something useful to myVariable
export {myFunction, myVariable};
// In childModule2.js
let myClass = ...; // assign something useful to myClass
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'

名前付きエクスポートの使用

my-module.js モジュールの中で、以下のコードをインクルードすることができます。

// "my-module.js" モジュール
function cube(x) {
  return x * x * x;
}

const foo = Math.PI + Math.SQRT2;

var graph = {
  options: {
      color:'white',
      thickness:'2px'
  },
  draw: function() {
      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();
console.log(cube(3)); // 27
console.log(foo);    // 4.555806215962888

以下の点に注意することが重要です。

  • このスクリプトを HTML の <script> 要素で type="module" を指定したものに入れる必要があり、そうすれば適切にモジュールとして認識され、扱われます。
  • file:// の URL で JavaScript モジュールを実行することはできません。 — CORS エラーになります。 HTTP サーバーを通して実行する必要があります。

デフォルトエクスポートの使用

値をひとつエクスポートしたい、あるいはモジュールでフォールバック先の値を持ちたい場合は、デフォルトエクスポートを使用するとよいでしょう。

// module "my-module.js"

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

別のスクリプトからの、デフォルトエクスポートのインポートは簡単です。

import cube from './my-module.js';
console.log(cube(3)); // 27

仕様書

仕様書
ECMAScript (ECMA-262)
Exports の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
exportChrome 完全対応 61Edge 完全対応 16
完全対応 16
完全対応 15
無効
無効 From version 15: this feature is behind the Experimental JavaScript Features preference.
Firefox 完全対応 60
完全対応 60
未対応 54 — 60
無効
無効 From version 54 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference. To change preferences in Firefox, visit about:config.
IE 未対応 なしOpera 完全対応 48Safari 完全対応 10.1WebView Android 未対応 なしChrome Android 完全対応 61Firefox Android 完全対応 60
完全対応 60
未対応 54 — 60
無効
無効 From version 54 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference. To change preferences in Firefox, visit about:config.
Opera Android 完全対応 45Safari iOS 完全対応 10.3Samsung Internet Android 完全対応 8.0nodejs 完全対応 13.2.0
補足
完全対応 13.2.0
補足
補足 Modules must either have a filename ending in .mjs, or the nearest parent package.json file must contain "type": "module". See Node's ECMAScript Modules documentation for more details.
完全対応 12.0.0
補足 無効
補足 Modules must either have a filename ending in .mjs, or the nearest parent package.json file must contain "type": "module". See Node's ECMAScript Modules documentation for more details.
無効 From version 12.0.0: this feature is behind the --experimental-modules runtime flag.
完全対応 8.5.0
補足 無効
補足 Module filenames must end with .mjs, not .js. See Node's ECMAScript Modules documentation for more details.
無効 From version 8.5.0: this feature is behind the --experimental-modules runtime flag.
default keyword with exportChrome 完全対応 61Edge 完全対応 16
完全対応 16
完全対応 15
無効
無効 From version 15: this feature is behind the Experimental JavaScript Features preference.
Firefox 完全対応 60
完全対応 60
未対応 54 — 60
無効
無効 From version 54 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference. To change preferences in Firefox, visit about:config.
IE 未対応 なしOpera 完全対応 48Safari 完全対応 10.1WebView Android 未対応 なしChrome Android 完全対応 61Firefox Android 完全対応 60
完全対応 60
未対応 54 — 60
無効
無効 From version 54 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference. To change preferences in Firefox, visit about:config.
Opera Android 完全対応 45Safari iOS 完全対応 10.3Samsung Internet Android 完全対応 8.0nodejs 完全対応 13.2.0
補足
完全対応 13.2.0
補足
補足 Modules must either have a filename ending in .mjs, or the nearest parent package.json file must contain "type": "module". See Node's ECMAScript Modules documentation for more details.
完全対応 12.0.0
補足 無効
補足 Modules must either have a filename ending in .mjs, or the nearest parent package.json file must contain "type": "module". See Node's ECMAScript Modules documentation for more details.
無効 From version 12.0.0: this feature is behind the --experimental-modules runtime flag.
完全対応 8.5.0
補足 無効
補足 Module filenames must end with .mjs, not .js. See Node's ECMAScript Modules documentation for more details.
無効 From version 8.5.0: this feature is behind the --experimental-modules runtime flag.
export * as namespaceChrome 完全対応 72Edge 完全対応 79Firefox 完全対応 80IE 未対応 なしOpera 完全対応 60Safari 未対応 なしWebView Android 未対応 なしChrome Android 完全対応 72Firefox Android 未対応 なしOpera Android 完全対応 51Safari iOS 未対応 なしSamsung Internet Android 完全対応 11.0nodejs 完全対応 12.0.0

凡例

完全対応  
完全対応
未対応  
未対応
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

関連情報