##はじめに
VueCLIを勉強中しているのですが、モジュールの使い方について、しっかりとした理解が必要だと気づいたので、今回はESModeulsの使い方についてまとめておきます。
大前提としてモジュール管理とは何かという話ですが、
**「ソースコードを分割して、メンテナンスをし易くするための仕組み」**のことです。
1つのファイルに全ての処理を記述すると、当然ですがコードは肥大化してきますし、メンテナンスも大変です。
その為、機能ごとに別ファイル(モジュール)に分割して必要に応じて読み込むことで、より効率なコードになるわけです。
ESModulesとは、ECMAScriptの規格に基づいたモジュール管理の仕組みで、主にブラウザ上で動作します。importやexportというキーワードを使って、モジュールの読み込みや出力を行います。
他にもNode.jsで動作する、Common.jsというモジュール管理の仕組みもあります。
こちらはrequireやexportsというキーワードを使い、モジュールの読み込みを行います。(しっかりと試せていませんが)
モジュール管理する方法は、実行環境などによって異なる種類があるということですね。
##ESModulesを試す
では、実際にESModulesのモジュール管理のやり方を試していきましょう。
まず、moduleAとmoduleBという名前のjsファイルと、ブラウザで結果を確認するのでhtmlを用意します。
let num = 10;
function methodA(){
console.log("This number : " + num);
}
//num変数と、methodAメソッドをエクスポート。
export {num,methodA};
//インポート
import {num ,methodA} from "./moduleB.js";
console.log(num); // 10
methodA(); // This number : 10
<body>
//typeをmoduleと指定する。
<script type="module" src="moduleA.js"></script>
</body>
まず最初に、モジュール管理を行う場合、**スクリプト読み込み時にtype="module"
を指定する必要があります。**この指定が無いとESmodulesは使えません。
moduleBでは、オブジェクトリテラルにexportしたい変数や関数を指定します。
moduleAでは、importの後に、**moduleBでの指定と同じ様に{num ,methodA}
**とします。ここで、export時と異なる命名にすると、エラーになるので注意しましょう。
そして、fromの後に、どのファイルからのimportをするかを指定します。ちなみにファイル指定では、../などパス指定をする必要があります。 from 'moduleB.js'
のように、ファイル名だけではエラーとなります。また、拡張子の.jsも省略できないのでご注意を。
こうすることで、moduleAでmoduleBの変数や関数を扱うことができるようになりました!
またexportとimportのモジュール名は同名にする必要があると言いましたが、asを使うことで別名の変数や、関数に変更することも可能です。
//asで名前変更
import {num as n ,methodA as A} from "./moduleB.js";
console.log(n); // 10
A(); // This number : 10
モジュール管理の基本的な流れは、こんな感じですが、
実はexportの方法は2種類あります。上のやり方は名前付きexportとなります。
次は、もう1つのexport defaultのやり方を見ていきましょう。
##export default
class Person{
constructor(val){
this.val = val;
}
print(){
console.log(this.val * 2);
}
}
//デフォルトエクスポート
export default Person;
import Person from "./moduleB.js";
const person = new Person(10);
console.log(person.val); //10
person.print(); // 20
今回はmoduleBでクラスを作り、それをmoduleAでimportします。
名前付きexportとの違いは、出力できるモジュールの数です。
名前付きexportでは、先ほどの例の様に、変数や関数など複数のモジュールをエクスポートできますが、
export defaultの場合、エクスポートできるモジュールの数は1つとなります。
なので例えば、下記の様に複数のクラスをexport defaultすることはできません。
class Person{
constructor(val){
this.val = val;
}
print(){
console.log(this.val * 2);
}
}
class Child{
constructor(val){
this.val = val;
}
print(){
console.log(this.val * 2);
}
}
//複数エクスポートはできない。エラー
export default {Person,Child}; //SyntaxError:
また、defaultを使った場合、importのモジュール名はasを使うことなく変更することができます。
//例えばモジュール名をPに変更
import P from "./moduleB.js";
//Pでインスタンス化
const person = new P(10);
console.log(person.val);
person.print();
ちなみに、defaultは1つのスクリプトファイルに対して、1つという決まりがありますが、
名前付きexportは複数記述が可能です。
なので、例えば以下の様に複数に分けてexportをすることもできます。
class Person{
constructor(val){
this.val = val;
}
print(){
console.log(this.val * 2);
}
}
let num = 300;
function methodA(){
console.log("This number : " + num);
}
function methodB(){
console.log("Hello World");
}
export default Person;
//exportを複数回使用
export {num,methodA};
export {methodB};
importでも、分割して読み込むことができます。
まとめて読み込みたい場合は、下の様にまとめて読み込むことも可能です。
//分けることもできる。必要に応じて読み込み。
import P from "./moduleB.js";
import {num} from "./moduleB.js";
import {methodA} from "./moduleB.js";
import {methodB} from "./moduleB.js";
//まとめてimportもできる。
import P,{num, methodA,methodB} from "./moduleB.js";
以上、ESmodulesでのモジュール管理についてでした。ありがとうございました。
##参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import