Help us understand the problem. What is going on with this article?

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

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
});
senou
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした