MENU

【Javascript基礎】EsModuleのExportとImportについて

他の方が作ってくれたテンプレートをそのまま使いまわしているため、このexportとimportの意味をわからず使用していました。
ちょうど、別の講座を受けたときに、そんな意味があったんだ!と細かい違いを知ったので、まとめておきたいと思います。

CONTENTS

そもそもESModuleとは?

ES modulesは、ES2015仕様において策定された、JavaScriptファイルから別のJavaScriptファイルを読み込む仕組みです。

これだけ聞いてもよくわかりません。。。

それでは、このESModule以前はどのような読み込み方をしていたのかというと、下記のように複数のjsファイルを読み込むのが一般的だったようです。うちの社内でも、けっこうこんな感じで読み込んでいます。
※こんなaccordionだけで単体で書くことはないと思いますが、後で説明しやすいようにそうしています。

<script src=”js/vender/jquery.min.js”></script>
<script src=”js/accordion.js”></script>
<script src=”js/slider.js”></script>
<script src=”js/main.js”></script>

上記をESModuleを導入すると、どうなるかというと、読み込むscriptが一つでよくなります。

<script src=”js/main.js”></script>

どうして、main.jsだけでよくなるのか?main.jsの中を見てみましょう。

import jquery from "./vender/jquery.min.js";
import accordion from "./accordion.js";
import  slider from "./slider.js";

jquery();
accordion();
slider();

importという記述がありますね。これがEsmoduleのimportになります。そして、exportは、importさせるために必要な記述になるのですが、importさせるjsファイル側に記述します。次で説明していきたいと思います。

と、その前に、こんなこと思った人いませんか?

accordionやsliderなどは、main.jsで一つのファイルに記述してもいいのではないか?

そうですよね!わたしも思いました!

これ、記述がそこまで長くないならそれでもいい気がするのですが、一つのファイルにずらーと記述すると、どこになんの記述を書いてあるのか探すのが大変です。

実際、わたしも自分で書いていて、この記述はどこにあるんだ!と探し回ったことがあります。

そしてチームで開発するとなったら、一つのファイルで管理すると、もっと大変。

ですので、モジュールで管理をすると、どこに何を記述しているのか、探しやすいのかなと思います!

他にも利点はあるようですが、あまりよくわかりませんでした。。下記サイトを参考ください!

ICS MEDIA
ES Modules入門 - JavaScriptでモジュールを使う時代 - ICS MEDIA JavaScriptには、モジュールという仕組みがあります。ECMAScript2015のModulesの標準仕様として策定されており、現在はすべてのブラウザで利用できます。

バンドラーを使用せずにES Modulesを使う

わたしは、webpackを使用してバンドルしているので、知らなかったのですが、バンドラーなしでこのEsmoduleを使用したい場合、type=”module”と記述する必要があります。

<script type="module" src="main.js"></script>

なんとなくふんわりで認識していたのですが、バンドラーは、現行ブラウザでもモジュールの仕組みを利用できるように、JSを変換してくれてたようです。

ですので、このtype=”module”をつけなくても読み込めていたんですね。

こういう細かいところの理解ができていなかったので、いい勉強になりました。

また、現在のブラウザではだいたい使用できそうです。バージョンによっては対応していないブラウザもありますが、2017-2018年以前のバージョンなので、使用してもいいように思います。

ImportとExportについて

前提として、ディレクトリ構成を下記の通りとします。

├──index.html
      ├── js/
          ├──main.js
          ├──module.js
 

上記の構成でいくと、index.htmlの記述は下記です。

完成ソース

全体のソースは下記です。

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>テスト</title>
    <script type="module" src="main.js"></script>
  </head>
  <body>
    <h1>テスト</h1>
  </body>
</html>

main.jsを読み込むときは、type=”module”を追記すること

module.js

//①exportできるよう定義した関数
export const hello = () => {
  console.log("hello!");
};

//②クラスをexportとして定義
class User {
  constructor(name) {
    this.name = name;
  }

  hello() {
    console.log(this.name);
  }
}
export { User }

//③export defaultと定義した関数
const funcB = () => {
  console.log("デフォルトだよ");
};

export default funcB;

main.js

import {hello} from "./module.js";
import {User} from "./module.js";
import functionB from "./module.js";

//①exportできるよう定義した関数を呼び出す
hello();

//②クラスをexportとして呼び出しをする
const user = new User('名前です');
user.hello();

//③export defaultと定義した関数を呼び出す
functionB();

今回、呼び出し方として3パターンあります。

①exportできるよう定義した関数を呼び出す

下記の関数を、exportと記述することで、外部のjsファイルでも呼び出せるように宣言しています。
module.jsの記述はこちら↓

export const hello = () => {
  console.log("hello!");
}

これをmain.jsで呼び出したいときは、こちら↓

import {hello} from "./module.js";
hello();

②クラスをexportとして呼び出す

クラスを呼び出したいときの、module.jsは下記

class User {
  constructor(name) {
    this.name = name;
  }

  hello() {
    console.log(this.name);
  }
}
export { User }

main.jsでは、下記を記述して、呼び出します。

import {User} from "./module.js";

const user = new User('名前です');
user.hello();

③export defaultと定義した関数を呼び出す

こちらは少し特殊で、一つのファイルに一つだけexport defaultとして定義ができます。
module.jsの記述はこちら↓

const funcB = () => {
  console.log("デフォルトだよ");
};
export default funcB;

また呼び出し方も他の2つと違い、関数名が同じでなくても読み込めます。
main.jsの記述はこちら↓

import functionB from "./module.js";
functionB();

関数名は、funcBだが、importする際は、functionBと名前が違いますが、読み込みができます。
ただ、名前が違うと保守性がよくないと思うので、基本的には同じ名前のほうがいいと思います。

importの記述を省略できます

今回、同じファイル名からの呼び出しなので、importの記述を省略もできます。

下記のように、カンマで区切って呼び出させることが可能です。

import {hello, User} from "./module.js";
import functionB from "./module.js";

さらに、こちらを一つにまとめることもできます。

import functionB, {hello, User} from "./module.js";

通常、一ファイルについて、一関数(export default)での運用が多いのかなと思うので、あまり使用する箇所はないかもしれませんが、このように記述することもできます。

そして、もう一点、バンドラーを使用すると、.jsを記述しなくても、補完をしてくれるようです。

ですので、webpackなどを使用して構築する際は、.jsを記述しなくてもよくなるので、下記のようになります。

import functionB, {hello, User} from "./module";

わたしが使用しているテンプレートは、他の方が実装しているものを使いまわしていたため、.jsの記述ないなと思いつつも、なぜなのか特に気にしたことがありませんでした。

ですので、今回webpackが補完してくれているんだと知れたので、よかったです。

まとめ

こういう細かい違いなど意識せずにバンドラーツールなどを使用していたので、概念を理解できてよかったです。

最近は、いろんなビルドツールが増えてきており、追いつくのが大変です。。

ただ、モダンなフロントエンドの開発スタイルだと思うので、基礎をしっかり押さえていきたいです。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
CONTENTS