文書の過去の版を表示しています。
— y2sunlight 2021-06-07
JavaScriptではES2015*2015からモジュールがサポートされました。近年では、モジュールはサーバーサイド、クライアントサイド(ブラウザ)のいずれでも利用できます。
モジュールは一つのファイルとして定義され、外部からアクセスできるメンバ(クラス、関数、変数、定数など)にはexportキーワードを付与します。以下はStudentクラスの例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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キーワードを使用します。
1 2 3 4 |
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要素に対して個々に別名をつけることができます。
1 2 3 |
import {School as MySchool, Student as MyStudent} from './school.js' var abc_school= new MySchool( 'ABC School' ); var suzuki= new MyStudent( 'Suzuki' ); |
アスタリスク( *
)を使用してモジュール内のすべての要素をインポートすることができます。但しこの場合、モジュールに対して別名を付与します。
1 2 3 |
import * as school from './school.js' var abc_school= new school.School( 'ABC School' ); var suzuki= new school.Student( 'suzuki' ); |
エクスポートする要素が1つのモジュールの場合、デフォルトのexport要素を宣言することができます。
1 2 3 4 5 6 |
export default class { constructor(name) { // プロパティの定義 this .name = name; } } |
この様にデフォルトのエクスポートでは要素に名前(この例の場合はクラス名)をつける必要はありません。インポートは以下の様にして行います。
1 2 |
import School from './school.js' var abc_school= new School( 'ABC School' ); |
モジュールを HTMLに適用するには、スクリプト要素の中でtype=“module” を使用します。import と export 文は、モジュールの中でのみ使うことができます。通常のスクリプト(type=“javascript”)の中では使えません。
以下は、上述のStudentクラスをインポートするChromeでの例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<! DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" > < title ></ title > </ head > < body > < script type = "module" > import { Student } from './student.js' var suzuki = new Student('suzuki'); suzuki.greeting(); // I am suzuki. </ script > </ body > </ html > |
importキーワードの中のモジュール名は、ChromeなどのクライアントサイドJavaでは拡張子を指定したパス名を指定します。
CORS(Cross-Origin Resource Sharing)とは、直訳すると「オリジン間リソース共有」となり、コルスとも呼ばれます。オリジンとはドメインと似ていますが、プロトコルとポート番号を含んだ概念です。
つまり、CORSとは異なったオリジン間でリソースを共有する仕組みのことで、CORSを使わない場合は、セキュリティの観点から同一オリジンポリシーに従います。例えばXMLHttpRequestはその代表例です。
CORSはモジュールのインポートに対しても有効になります。従って、モジュールを使ったJavaScriptをローカルでテストしようとするときは注意してください。ローカルから HTML ファイルを読み込もうとすると、JavaScript モジュールのセキュリティ要件のために、CORS エラーが発生します。テストはサーバー経由で行う必要があります。
モジュールの機能は単独のスクリプトのスコープに対してインポートされます。インポートされた機能はインポートしたスクリプトの内部からしかアクセスできません。即ち、インポートされた機能はグローバルスコープから利用することはできません。
1 2 3 4 5 6 7 |
mport { 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<! DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" > < title ></ title > </ head > < body > < script type = "module" src = "main.js" ></ script > < script > console.log(local_school.name); // NG foo_school = new School('Foo School') //NG </ script > </ body > </ html > |
TODO:module内ではグローバル変数が使えない?