当セクションはSystemJSを使ったWEBフロントエンド開発について説明します。JavaScriptをロードするための最も基本的な方法はscriptタグで実現することですが、SPAを構築するフロントエンド開発においては、モジュール分けして開発する事が前提であり、大量のscriptタグを記述する必要性やモジュールの依存関係により記述順番も非常に重要になります。そのため、モジュールの依存関係を解決するためのモジュール管理ツールは非常に重要な位置づけになっています。
SystemJSの概要
SystemJSはJavaScriptファイルの依存関係を解決するためのモジュール管理ツールで、ES6/AMD/CommonJS/UMDのモジュールをサポートしているモジュールローダです。
例えばa.component.tsファイルで同じフォルダにあるb.component.tsのクラスをimportするとき、「import {xxx} from './a.component'」のように記述しますが、 同じ場所には同じファイル名の.tsファイルと.jsファイルが存在している場合が多いと思います。TypeScriptのコンパイラはtsファイルからjsファイルの変換をしても、ブラウザで実行するときにファイルが見つからないエラーが発生します。これを解決するためには後述するpackagesのdefaultExtension指定が必要になります。また、Lodashのようなライブラリをimportしようとするとき、「import * as _ from 'lodash'」のように書きますが、 lodashモジュールがどこに存在するかの指定がないとブラウザで実行するときにファイルが見つからないエラーになります。このようにモジュール解決を行う管理ツールの1つがSystemJSになります。
SystemJSの説明
import文の説明
モジュールをロードするのに使うメソッドで、import()はPromiseを返します。
Promiseがモジュールのオブジェクトで解決すると、then()のコールバックが実行されます。
Configuration API(systemjs.config.js)の説明
baseUrl
- ロードするモジュールの起点を示すパスです。
- baseUrlで設定するパスからの相対パスでモジュール名を解決しようとします。
- ソース内で明示的に相対パスや絶対パスが指定された場合はそちらを優先します。
- baseURL、paths、mapをうまく組み合わせて実体ファイルまでのパスを正確に指定しておかないと、 ブラウザで実行するときにファイルが見つからないエラーになります。
例)下記の場合は、Load module-A from /modules/module-A
1 2 3 4 |
SystemJS.config({ baseURL: '/modules' }); System.import('module-A'); |
「/」を指定すると、この後の全てのパス指定はルートが基準となる。
baseURLを省略するか、又は、「.」に設定すると、呼び出し元のindex.htmlが存在するパス(例:(root)/src/)がbaseURLとなる。
paths
- map定義と類似。 ワイルドカードが使えます。
- baseURL、paths、mapをうまく組み合わせて実体ファイルまでのパスを正確に指定しておかないと、 ブラウザで実行するときにファイルが見つからないエラーになります。
- pathsプロパティで「node:* : ../node_modules/*」と指定すると、mapプロパティ内のnode:を../node_modules/で置き換えられる。
map
- モジュールの場所を設定する。
- import文のfrom句以降のエイリアスを定義する。
- baseURL、paths、mapをうまく組み合わせて実体ファイルまでのパスを正確に指定しておかないと、 ブラウザで実行するときにファイルが見つからないエラーになります。
- mapで「lodash : node:lodash/index.js」と指定すると、 System.import('lodash')と書いたときに(root)/node_modules/lodash/index.jsを参照することになる。
1 2 3 4 5 |
SystemJS.config({ map: { jquery: '//code.jquery.com/jquery-2.1.4.min.js' } }); |
1 |
import $ from 'jquery'; |
packages
- モジュールのロード属性(例:ファイル名、拡張子、依存関係等)を定義
- defaultExtension: 'js'と指定している場合は、フォルダにtsファイルとjsファイル が両方存在する場合、指定と一致するjsファイルを参照する。
meta
- 依存関係を記述できる。
transpiler
- モジュールをロードした際に使用するトランスパイラを指定する(実行時コンパイルに使いたいライブラリを指定する)
- 「traceur」(デフォルト)や、「typescript」、「babel」を指定する
- 特に指定しない場合は
false
にする。
typescriptOptions
- transpilerにtypescriptを使用した際の、TypeScriptコンパイラのオプション
Angularjs2の公式チュートリアルにあるクイックスタートのConfiguration APIの説明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
/** * System configuration for Angular samples * Adjust as necessary for your application needs. */ (function (global) { System.config({ paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { // our app is within the app folder 'app': 'app', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', // other libraries 'rxjs': 'npm:rxjs', 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { app: { defaultExtension: 'js', meta: { './*.js': { loader: 'systemjs-angular-loader.js' } } }, rxjs: { defaultExtension: 'js' } } }); })(this); |
baseUrl
- baseURLを省略しているので、呼び出し元のindex.htmlが存在するパス「(root)/src/」がbaseURLとなる。
paths
- 'node_modules/'のエイリアスとして'npm:'を定義している。
map
- 'app'はappフォルダ配下を定義
- angularとそれ以外で使用されたライブラリは、'npm:'でパスを指定
packages
- appフォルダ配下のデフォルト拡張子とローダ定義
- rxjsモジュールのデフォルト拡張子を定義
以下、参考にさせて頂いたページです。ありがとうございました。