ES6のexport/import構文をScalaと比べながら解説

プログラミング#JavaScript#ES6#Scala
suin
suin
2015年10月13日 投稿
image.png (56.9 kB)

ES6ではexportimportが追加されてモジュール化が明示的にできるようになりました。

自分はサーバサイドをScalaで書いているのですが、
Scalaのimportなどと比べると、ES6は結構違ったので、
気づいた点をまとめてみました。

ファイル名が明示的

ScalaやGoにはコンパイルがあるので、importを宣言する場合ファイル名を指定する必要がないが、ES6ではimportするときファイル名を明示する必要になる。

つまり、Scalaのimport FooはES6ではimport Foo from "./Foo"となる。これはどうしようもない。同じスクリプト言語のPHPですらオートローダーがあるのに…。

ES6は"public"であることを明示する派

ScalaにもES6にもパッケージのプライバシーがあるが、公開・非公開どちらを明示的にするかの戦略が異なる。Scalaはデフォルトでpublicになり、非公開をprivateキーワードで明示する。一方、ES6はデフォルトがprivateで、公開するものをexportキーワードで明示する。

private

Scalaでは公開がデフォルトなので、非公開は明示する。

scala
private class Foo

ES6では非公開がデフォルト。

es6
class Foo {}

public

Scalaでは公開がデフォルト。

scala
class Foo

ES6は非公開がデフォルトなので、公開はexportで明示する。

es6
export class Foo {}

exportのバリエーション

exportのしかたにもバリエーションがある。

export default

ある変数をモジュールとして公開する。1ファイル、1クラス向き?

Hello.js
export default class Hello {
  greeting() {
    console.log("hello!");
  }
}
app.js
import Hello from "./Hello";
new Hello().greeting();

export

変数をモジュールのメンバとして公開する。クラスに名前をつけてexportするとき。

Hello.js
export class Hello {
  greeting() {
    console.log("hello!");
  }
}

export class GutenTag {
  greeting() {
    console.log("Guten Tag!");
  }
}
app.js
import {Hello, GutenTag} from "./Hello";
new Hello().greeting();
new GutenTag().greeting();

export {...}

変数をモジュールのメンバとして公開する。クラスに名前をつけて、あとでまとめてexportするとき。

Hello.js
class Hello {
  greeting() {
    console.log("hello!");
  }
}

class GutenTag {
  greeting() {
    console.log("Guten Tag!");
  }
}

export {Hello, GutenTag};
app.js
import {Hello, GutenTag} from "./Hello";
new Hello().greeting();
new GutenTag().greeting();

export { ... as ... }

変数をモジュールのメンバとして公開する。名前を変えて公開する場合に使う。

Hello.js
class GreetingInEnglish {
  greeting() {
    console.log("hello!");
  }
}

export {GreetingInEnglish as Hello};
app.js
import {Hello} from "./Hello"
new Hello().greeting();

importのバリエーション

import ... from "..."

最も典型的なimport宣言。

js
import Hello from "./Hello";

Hello.jsがHelloexport defaultしている場合にだけ使える。

import { ... } from "..."

これも典型的なimport宣言。

js
import { Hello } from "./Hello";

Hello.jsがHelloを単にexportしている場合にだけ使える。

import { ..., ... } from "..."

同じファイルから、いくつか一度にimportする宣言。

js
import {Hello, GutenTag} from "./Hello";

上のコードは下と同じ。

js
import {Hello} from "./Hello";
import {GutenTag} from "./Hello";

import { ... as ... } from "..."

名前を変えてimportする宣言。

js
import {Hello as EnglishGreeting} from "./Hello";
new EnglishGreeting().greeting();

Scalaのimport {Foo => Bar}のようなもの。

import * as ... from "..."

モジュールまるごと名前を変えてimportするケース。

js
import * as Greetings from "./Hello";
new Greetings.Hello().greeting();
new Greetings.GutenTag().greeting();

まとめ

  • ES6のimportはファイル名を明示する必要あり
  • ES6は"public"であることを明示する(デフォルトはprivate)
  • ScalaとES6でだいぶ書き方が違う

解説に間違っている部分があれば教えて下さい!