====== JavaScript モジュール ======
--- //[[http://www.y2sunlight.com/water|y2sunlight]] 2021-06-07//
===== モジュールの構文 =====
JavaScriptではES2015[[js:top#ECMAScript|*2015]]からモジュールがサポートされました。近年では、モジュールはサーバーサイド、クライアントサイド(ブラウザ)のいずれでも利用できます。
==== export ====
モジュールは一つのファイルとして定義され、外部からアクセスできるメンバ(クラス、関数、変数、定数など)にはexportキーワードを付与します。以下はStudentクラスの例です。
export class School {
constructor(name) {
// プロパティの定義
this.name = name;
}
}
export class Student {
// コンストラクタの定義
constructor(name) {
// プロパティの定義
this.name = name;
}
// メソッドの定義
greeting() {
console.log(`I am ${this.name}.`);
}
}
export構文
export let name1, name2, …, nameN; // 変数(var, const も)
export function functionName(){...} // 関数
export class ClassName {...} // クラス
> TODO 説明
==== import ====
モジュール内のメンバをインポートするにはimportキーワードを使用します。
import { School, Student } from './school.js'
var abc_school = new School('ABC School');
var suzuki = new Student('Suzuki');
suzuki.greeting(); // I am Suzuki.
import構文
import { name, ・・・ } from module
name: インポートする要素
module: モジュール
> TODO 説明
> モジュール名はNode.jsなどのサーバーサイドJavaでは拡張子を省略したパスを、ChromeなどのクライアントサイドJavaでは拡張子を指定したパス名を指定します。
\\
===== 様々な構文 =====
==== importしたメンバの別名 ====
モジュール内のimport要素に対して個々に別名をつけることができます。
import {School as MySchool, Student as MyStudent} from './school.js'
var abc_school= new MySchool('ABC School');
var suzuki= new MyStudent('Suzuki');
==== ワイルドカードによるimport ====
アスタリスク( ''*'' )を使用してモジュール内のすべての要素をインポートすることができます。但しこの場合、モジュールに対して別名を付与します。
import * as school from './school.js'
var abc_school= new school.School('ABC School');
var suzuki= new school.Student('suzuki');
==== デフォルトのexport ====
エクスポートする要素が1つのモジュールの場合、デフォルトのexport要素を宣言することができます。
export default class {
constructor(name) {
// プロパティの定義
this.name = name;
}
}
この様にデフォルトのエクスポートでは要素に名前(この例の場合はクラス名)をつける必要はありません。インポートは以下の様にして行います。
import School from './school.js'
var abc_school= new School('ABC School');
\\
===== クライアントサイドでの利用 =====
モジュールを HTMLに適用するには、スクリプト要素の中でtype="module" を使用します。import と export 文は、モジュールの中でのみ使うことができます。通常のスクリプト(type="javascript")の中では使えません。
以下は、上述のStudentクラスをインポートするChromeでの例です。
importキーワードの中のモジュール名は、ChromeなどのクライアントサイドJavaでは拡張子を指定したパス名を指定します。
==== CORSに関する注意 ====
CORS(Cross-Origin Resource Sharing)とは、直訳すると「オリジン間リソース共有」となり、コルスとも呼ばれます。オリジンとはドメインと似ていますが、プロトコルとポート番号を含んだ概念です。
* y2sunlight.com --- ドメイン
* http://y2sunlight.com:80 --- オリジン
つまり、CORSとは異なったオリジン間でリソースを共有する仕組みのことで、CORSを使わない場合は、セキュリティの観点から[[https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy|同一オリジンポリシー]]に従います。例えば[[https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest|XMLHttpRequest]]はその代表例です。
CORSはモジュールのインポートに対しても有効になります。従って、モジュールを使ったJavaScriptをローカルでテストしようとするときは注意してください。ローカルから HTML ファイルを読み込もうとすると、JavaScript モジュールのセキュリティ要件のために、CORS エラーが発生します。テストはサーバー経由で行う必要があります。
==== グローバルスコープに関する注意 ====
モジュールの機能は単独のスクリプトのスコープに対してインポートされます。インポートされた機能はインポートしたスクリプトの内部からしかアクセスできません。即ち、インポートされた機能はグローバルスコープから利用することはできません。
また、モジュールの場合、自動的に [[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Strict_mode|Strict モード]]になり、var命令の省略は禁止されます。
import { School } from './school.js'
var local_school = new School('Local School');
console.log(local_school.name); // OK
// モジュール内ではグローバルスコープを持つ変数が作成できない。
// global_school = new School('Global School');
// console.log(global_school.name); NG
export class School {
constructor(name) {
// プロパティの定義
this.name = name;
}
}
\\