SeaJS入門教程シリーズの使用SeaJS(二)


ダウンロードとインストール
プロジェクトの中でSeaJSを使うには、あなたが必要とするすべての準備作業はsea.jsをダウンロードしてあなたのプロジェクトのある場所に置くことです。SeaJSプロジェクトは現在GitHubに委託されています。ホームページはhttps://github.com/seajs/seajs/ 。そのgitライブラリのbuildディレクトリでsea.js(圧縮済み)またはsea-debug.js(非圧縮)をダウンロードすることができます。ダウンロードが完了したら、プロジェクトの該当位置に置いて、ページの中に「script」のタグを通して導入すれば、SeaJSが使えます。
SeaJS基本開発原則
SeaJSの具体的な使用を検討する前に、SeaJSのモジュール化理念と開発原則を紹介します。SeaJSを使ってJavaScriptを開発する基本原則はすべてモジュールです。SeaJSを導入すると、JavaScriptコードを作成するモジュールになります。SeaJSではモジュールの概念はオブジェクト指向のクラスに似ています。モジュールはデータと方法を持つことができます。データと方法は公共またはプライベートとして定義できます。共通データと方法は別のモジュールで呼び出すことができます。また、各モジュールは、個々のjsファイル、すなわち対応するモジュールに定義されるべきである。モジュールの作成と呼び出しについて説明します。
モジュールの定義と作成
モジュール定義関数defineSeaJSで「define」関数を使用してモジュールを定義します。SeaJSの文書はdefineに関する完全な参照がないので、SeaJSソースコードを読みました。defineは3つのパラメータを受け取ることができます。
上はSeaJSソースから抜粋したものです。defineで受信できるパラメータはそれぞれモジュールIDです。モジュール配列と工場関数に依存します。ソースコードを読んで、defineが異なるパラメータの個数に対する解析規則は以下の通りです。もし一つのパラメータがあるなら、factoryに値を与えます。二つのパラメータがあれば、二つ目はfactoryに割り当てられます。最初にarrayであればdepsに値を割り当て、そうでなければidに値を与える。3つのパラメータがある場合は、それぞれid、deps、factoryに値が割り当てられます。しかし、SeaJSの公式例を含め、ほとんどのところでdefineを使用しているところは一つの工場関数だけを伝達しています。
個人的な提案はSeaJSの公式例の基準に従い、一つのパラメータのdefineでモジュールを定義する。idとdepsはどうなりますか?IDはモジュールの識別文字列であり、defineはパラメータが一つしかない場合、このためのjsファイルの絶対パスはIDによってデフォルトで割り当てられます。example.comのa.jsファイルにdefine定義モジュールを使用すると、このモジュールのIDはhttp://example.com/a.js 特にidに入らないようにアドバイスする必要はありません。depsも一般的に入る必要がないです。必要なモジュールはrequireでロードすればいいです。
工場関数factory解析
工場関数はモジュールの主体と重点です。一つのパラメータだけをdefineに渡す時(推奨書き方)、このパラメータは工場関数です。この時、工場関数の三つのパラメータはそれぞれ:1.require――モジュールローディング関数で、依存モジュールを記載するために使用されます。2.exports――インターフェースポイントで、データまたは方法を定義すると、それを外部に暴露して呼び出します。3.モジュールのメタデータ。この3つのパラメータは必要に応じて指定を表示するかどうかを選択できます。次にmoduleを話します。moduleは対象として、モジュールのメタ情報を格納しています。具体的には、以下の通りです。1.module.id――モジュールのIDです。2.module.dependencies――このモジュールに依存するすべてのモジュールのIDリストが格納されています。3.module.export――exportsと同じ対象を指す。
モジュール作成の3つのモード
第1の定義モジュールのモードは、exportsに基づくモードである。
/**
* Defines a module.
* @param {string=} id The module id.
* @param {Array.|string=} deps The module dependencies.
* @param {function()|Object} factory The module factory function.
*/
fn.define = function(id, deps, factory) {
    //code of function…
}
上は「正統」を比較するモジュール定義モードです。パブリックデータおよび方法をexportsに付加することに加えて、次のコードと上のコード機能が同じであるように、オブジェクト表示モジュールに直接戻すこともできる。
モジュール定義に他のコードがない場合は、オブジェクトだけを返すという簡略化された書き方もあり得る。

define(function(require, exports, module) {
    //code of the module...
});
の第3の方法は、純粋なJSONデータを定義するモジュールに非常に適している。
モジュールのロードと参照
モジュールのアドレス指定アルゴリズムは上記で述べたように、モジュールはjsファイルに対応していますが、モジュールをロードする際には、一般的に、ロード関数に必要なモジュールに文字列パラメータを提供するので、文字列から実際のモジュールがあるファイルパスに対する解析アルゴリズムが必要です。SeaJSは以下の識別をサポートします。絶対アドレス――jsファイルの絶対パスを提供します。

define(function(require, exports, module) {
    var a = require('a'); // a
    var b = require('b'); // b

    var data1 = 1; //

    var func1 = function() { //
        return a.run(data1);
    }

    exports.data2 = 2; //

    exports.func2 = function() { //
        return 'hello';
    }
});
は、ロードの代表です。http://example/js/a.js 。相対アドレス――ロード関数のあるjsファイルの相対アドレスを相対的に呼び出してモジュールを探す。例えばhttp://example/js/b.js に
define(function(require) {
    var a = require('a'); // a
    var b = require('b'); // b

    var data1 = 1; //

    var func1 = function() { //
        return a.run(data1);
    }

    return {
        data2: 2,
        func2: function() {
            return 'hello';
        }
    };
});
をロードします。http://example/js/c.js 。基本アドレスアドレス――絶対パスでもないし、絶対パスでもない文字列の識別をロードするなら、SeaJSグローバル構成における「Base」に対してアドレスを探す方法は後で議論されます。注意上にモジュールをロードする時は、サフィックス名「.js」を伝えずに、SeaJSに自動的に「.js」を追加します。しかし、次の3つの場合は追加されません。cssをロードする場合、
define({
    data: 1,
    func: function() {
        return 'hello';
    }
});
パスに含まれています。
require("http://example/js/a");
パスを「隺」で締めくくる場合、例えば:
require("./c");
はアプリケーションシーンによって、SeaJSは三つのロードモジュールのAPIを提供しています。それぞれseajs.use、requireとrequire.asyncです。以下でそれぞれ紹介します。
seajs.use
seajs.useは主に入り口モジュールをロードするために使われます。入口モジュールはCプログラムのmain関数に相当し、モジュール全体がツリーに依存するルートでもあります。上のTinyAppの例では、initは入り口モジュールです。seajs.useの使い方は以下の通りです。
require("./module1-style.css");
は一般的にseajs.useはページで入り口モジュールをロードするだけで、SeaJSは入り口モジュールに沿ってすべての依存モジュールを解析して、それらをロードします。入口モジュールが一つしかないなら、sea.jsを導入するscriptタグに「data-main」属性を加えることによってseajs.useを省略してもいいです。例えば、上のTinyAppのindex.も以下のように書き換えられます。
require
requireはSeaJSの主なモジュールローディング方法であり、モジュールの中で他のモジュールを使用する必要がある場合は、一般的にrequireでローディングされます。
require(http://example/js/a.json?cb=func);
ここで簡単にSeaJSの自動ローディングメカニズムを紹介します。上記で述べましたが、SeaJSを使ってsea.jsを含めるだけでいいです。他のjsファイルはどうやって読み込まれますか?SeaJSはまず入口モジュールをダウンロードして、正規表現を使ってコードの中のすべてのrequireをマッチングさせて、またrequireの中のファイルパスの標識に基づいて相応のjsファイルをダウンロードして、ダウンロードしたjsファイルを繰り返します。プロセス全体は図のエルゴード動作に似ている(クロスサイクル依存性があるので、ツリーではなく全体の依存データ構造は図である)。上記のことが分かりました。requireに送るパスマークは文字列の字面量でなければいけません。表現ではなく、下のようにrequireを使う方法は間違っています。
require("http://example/js/a.json#");
はいずれもSeaJSが正しい正則と一致して、該当するjsファイルをダウンロードすることができなくなります。
require.async
SeaJSはhtmlページを開いたときに必要なすべてのjsファイルを静的に分析して一度に記録すると言っていましたが、もしあるjsファイルが必要な時にダウンロードするなら、require.async:

//
seajs.use('./a');

//
seajs.use('./a', function(a) {
  a.run();
});

//
seajs.use(['./a', './b'], function(a, b) {
  a.run();
  b.run();
});
を使ってこのモジュールを使う時だけ、対応するjsファイルが下に載せられます。JavaScriptコードのロードが必要です。
SeaJSのグローバル構成SeaJSは、グローバル構成を示す配置オブジェクトを受信するseajs.com fig方法を提供する。具体的な使用方法は、

<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>TinyApp</title>
</head>
<body>
    <p class="content"></p>
    <script src="./sea.js" data-main="./init"></script>
</body>
</html>
で、ベースアドレスがアドレス指定されたときのベースアドレスパスを示す。例えばベースはhttp://example.com/js/3-party/ を選択すると、
var m = require('/path/to/module/file');
が読み込まれます。http://example.com/js/3-party/jquery.js 。aliasは、長い一般的な経路に略語を設定することができる。charsetはjsをダウンロードする時scriptタグのcharset属性を表します。timeoutはダウンロードファイルの最大時間をミリ秒単位で表します。デバッグはデバッグモードで動作するかどうかを示します。
SeaJSはどうやって既存のJSライブラリと協力して使うのですか?
既存のJSライブラリをjQueryのようにSeaJSと一緒に使うには、SeaJSのモジュール定義規則に従って既存のライブラリをパッケージ化するだけです。例えば、以下はjQueryのパッケージ方法です。
require('module' + '1');
require('Module'.toLowerCase());
SeaJSプロジェクトのパッケージ展開
SeaJSはもともとパッケージ展開ツールspmを集めていましたが、作者はよりKISSするために、spmをSeaJSから外して、単独のプロジェクトになりました。spmの核心思想はすべてのモジュールのコードを合わせて圧縮して、入口モジュールに組み込むことです。SeaJS自体の特性のため、これは何も変える必要がなく、開発環境と生産環境の間で便利に切り替えられます。しかし、spmは正式版が発表されていませんので、詳しく紹介するつもりはありません。興味のある方はgithubプロジェクトのホームページをご覧ください。https://github.com/seajs/spm/。実際には、各項目に使われるJSの合併と圧縮ツールは違っていますので、spmは各項目に完全に適合していないかもしれません。SeaJSの原理を知ったら、自分でプロジェクトの特徴に合うパッケージスクリプトを書くことができます。