LoginSignup
618
526

More than 3 years have passed since last update.

ES6のexportについて詳しく調べた

Last updated at Posted at 2017-06-25

ES6のexportについて

webpackのチュートリアルとかがES6なので、読めないとやばい、開発のときは書けないとやばいということで調べてみました。

exportについて

モジュール化を行うexportには、モジュールごとに複数のexportを行うnamed exportsとモジュールごとに1つのexportを行うdefault exportsがある。

named exports

モジュールは前言の先頭にexportとつけることで、複数のモジュールをexportすることができる。

lib.js
export const sqrt = Math.sqrt;
export function square(x) {
  return x * x;
}
export function diag(x, y) {
  return sqrt(square(x) + square(y));
}
main.js
import { square, diag } from 'lib'; //libからsquareとdiagというモジュールをインポートする
console.log(square(11));
console.log(diag(4, 3));

モジュール全体をインポートして、named exportsをプロパティ表記法で参照することもできる。

import * as lib from 'lib'; // lib.jsの全てのモジュールをlibというオブジェクトに格納するみたいなイメージ
console.log(lib.square(11));
console.log(lib.diag(4, 3));

CommonJSと同じ記述で、Node.jsのモジュールのエクスポートと重複しないようにも書ける。

lib.js
var sqrt = Math.sqrt;
function square(x) {
  return x * x;
}
function diag(x, y) {
  return sqrt(square(x) + square(y));
}
module.exports = {
  sqrt: sqrt,
  square: square,
  diag: diag,
};
main.js
var square = require('lib').square;
var diag = require('lib').diag;
console.log(square(11));
console.log(diag(4, 4);

Default exports

フロントの開発でも、1つのモデルに付き1つのモジュールでコンストラクタやクラスが使われる。
ES6のモジュールは、最も重要なexportする値default exportという形で選択できる。

myFunc.js
export default function() {...};
main1.js
import myFunc from 'myFunc';
myFunc();

default exportsを使ったクラスのモジュールはこんな感じ。

myClass.js
export default class {...};
main2.js
import MyClass from 'MyClass';
let inst = new MyClass();

default exportの式の宣言は名前を持たない。
代わりに、モジュールの名前で識別する。

名前付きのDefault exports

ライブラリは単一の関数だが、追加のサービスはその関数のプロパティを通して提供される。
// ドキュメントを読んでもピンとこなかったのであとで調べます。

ドキュメントでは、CommonJSでのjQueryとUnderscope.jsの例があった。

underscore.js
var _ = function(obj) {
  ...
};
var each = _.each = _.forEach = function(obj, iterator, context) {
  ...
};
module.export = _;
main.js
var _ = require('underscope');
var each = _.each;

今や上記のCommonJSはES6モジュールとして書き直されている。
CommonJSよりもES6の方がフラットフラット

underscore.js
export default function(obj) {
  ...
};
export function each(obj, iterator, context) {
  ...
}
export { each as forEach };
main.js
import _, { each } from 'underscore';

default exportはnamed exportでもある

default exportは、実はdefaultという名前のエクスポート。
以下は同じ意味になる。

import { default as foo } from 'lib';
import foo from 'lib';

同じように以下の2つのモジュールも同義。

module1.js
export default 123;
module2.js
const D = 123;
export { D as default };

ES6のモジュールのデザインのゴール

  1. default exports推奨
  2. 静的なモジュール構成
  3. 同期と非同期両方のローディングをサポート
  4. モジュール間の巡回依存のサポート

英語力がなかったのと、イメージがつかめなかったのとであまり理解できず。。。。
あとで読み直す( http://2ality.com/2014/09/es6-modules-final.html )

import方法

ES6ではモジュールのimport方法はいくつかある。

// Default exports and named exports
import theDefault, { named1, named2 } from 'src/mylib';
import theDefault from 'src/mylib';
import { named1, named2 } from 'src/mylib';

// Renaming import named1 as myNamed1
import { named1 as myNamed1, named2 } from 'src/mylib';

// Importing the module as an object
//(with one property per named export)
import * as mylib from 'src/mylib';

// Only load the module, don't import anything
import 'src/mylib';

export方法

モジュールの中にあるものをエクスポートする方法は2つある。
exportで宣言を行う。

export var myVar1 = ...;
export let myVar2 = ...;
export const MY_CONST = ...;

export function myFunc() {
  ...
}
export function* myGeneratorFunc() {
  ...
}
export class MyClass {
  ...
}

default exportは関数やクラスを含む式。

export default 123;
export default function (x) {
  return x;
};
export default x => x;
export default class {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
};

モジュールの最後にエキスポートしたい全てを羅列できる。

const MY_CONST = ...;
function myFunc() {
  ...
}

export { MY_CONST, myFunc };

別の名前でもエキスポートできる。

const MY_NAME = ...;
function myFunc() {
  ...
}

export { MY_CONST as THE_CONST, myFunc as theFunc };

Re-exporting

Re-exportingとは、別のモジュールのエクスポートを現在のモジュールのエクスポートに追加すること。
他のモジュールの全てのエクスポートを追加することもできる。

export * from 'src/other_module';

より選択的なRe-exporting

export { foo, bar } from 'src/other_module';

// Export other_modules’s foo as myFoo
export { foo as myFoo, bar } from 'src/other_module';

ES6のモジュールローダー API

モジュールを扱う宣言の文法に加えて、APIもある。
APIでは以下のことができるようになる。

  • プログラムに依るモジュールとスクリプトの操作
  • モジュールの読み込みの設定
  • ローダーは、import … fromのモジュールの指示詞に従ってモジュールの読み込みなどの処理を行う。 コンストラクタはReflect.Loader。 各プラットフォームは、モジュールロードの得知恵のスタイルを実装するグローバル変数System(システムローダー)にカスタマイズされたインスタンスを保持する。

モジュールのインポート

プログラムでのモジュールのインポート。

System.import('some_module')
.then(some_module => {
  // Use some_module
})
.catch(error => {
  ...
});

System.import()は以下を可能にする。

  • scriptタグの中でモジュールが使えるようになる
  • 条件に合わせてモジュールを読み込める

System.importでは、単一のモジュールを取得する。
Promise.allを使用すると複数のモジュールをインポートできる。

Promese.all(
  ['module1', 'module2', 'module3']
  .map(x => System.import(x)))
.then(([module1, module2, module3]) => {
  // User module1, 2, 3
});
618
526
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
618
526