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


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

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では公開がデフォルトなので、非公開は明示する。

private class Foo

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

class Foo {}

public

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

class Foo

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

export class Foo {}

exportのバリエーション

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

export default

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

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

js:app.js

import Hello from "./Hello";
new Hello().greeting();

export

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

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

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

js:app.js

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

export {…}

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

js:Hello.js

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

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

export {Hello, GutenTag};

js:app.js

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

export { … as … }

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

js:Hello.js

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

export {GreetingInEnglish as Hello};

js: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でだいぶ書き方が違う

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