rejs - Vanilla JS Module Builderの紹介

このエントリは GREE Advent Calendar 2014 6日目の記事です。

皆さんこんにちは!Reflowしてますか?
13卒でArt部の和智(@watilde)です。業務では、GREE Platformで使われている内製 JS/CSS FrameWorkのコミッターとかしてます。

まえがき

弊社は、スマートフォンの黎明期よりブラウザ向けのアプリを開発してきました。環境の変化への追従や、度重なる機能追加でJavaScriptのコードの規模は肥大化していきました。

役割ごとにモジュール化をしてファイル分割を行わないと可読性が落ち、じわじわと保守コストが上がっていきます。しかし、古くからある秘伝のソースはAMDやCommonJSで書かれていないVanillaなJSです。r.js、Browserify、Webpack などのツールでモジュール化するにも、書き換えが大量に発生して導入するのはとっても②大変です。

そんな背景から、Vanilla JSのモジュール化を行う第一歩として、rejsと呼ばれるVanilla JSのModule Builderがグリーでは利用されています。今回は、そんなrejsの紹介を行います!

rejs - Vanilla JS Module Builderの紹介

rejsは、グリーに所属するJason Parrottによって開発されているOSSなVanilla JS Module Builderです。グリーでは、一部のゲームや内製のライブラリ開発で使用されています。

URL: https://github.com/Moncader/rejs

rejsの説明をVanilla JS Module Builderとしてみましたが、分かりやすく言うと「ファイルのリストをその内容に基づいてソートしてくれるツール」となります。

ファイルのリストをその内容に基づいてソート

ファイルのリストをその内容に基づいてソート

明確にexport/importの機能があるわけではありませんが、exportは「グローバルにプロパティ生やす」で、importは「ファイルに存在しないものを参照する」なのでModule Builderとして成立していると考えています。

仕組み

簡単に処理の流れについて

  1. ファイルの名前とソースを受け取る
  2. acornを使い、ファイルごとにソースのASTを取得
  3. ASTのNodeごとにファイルのGlobal Scopeにある変数の詳細とその状態を保持
  4. ファイルのGlobal Scopeごとに、内部で定義している変数と使用している変数を解析
  5. 以上を元に、依存関係を解決するように各Nodeを順序付けしてソート

実際に使ってみる

rejsを使うには、3つの方法があります。

  • rejsのcli
  • gruntプラグイン
  • gulpプラグイン

ぞれぞれ、実際に使ってみましょう。

構成例

いきなり使う前に、まずはファイル構成についての説明です。

下記のようなディレクトリ構成を例に話を進めていきます。

  • src
    • sampleOne.js
    • sampleTwo.js
    • sampleThree.js
  • dist
    • XmasPresent.js
  • test
    • fixture.js
    • test.js

srcディレクトリ内にソースファイルがあり、

distディレクトリに依存関係を解決し、結合済みのXmasPresent.jsを書き出すという想定です。

次に、それぞれのソースファイルについての説明します。

sampleOne.js

グローバル空間に宣言済みであろうxmasオブジェクトの

present.box.colorというプロパティにredという文字列を入れています。

sampleTwo.js

グローバル空間に宣言済みであろうxmasオブジェクトに

present.boxというプロパティを追加しています。

sampleThree.js

グローバル空間にxmasというオブジェクトを宣言しています。

さて、今回のケースでは

sampleThree.js, sampleTwo.js, sampleOne.jsの順に結合すれば正しく動作します。

期待する振る舞いとして、結合したものと比較して何も表示されなければOKとします。

使ってみる

環境を構築したら、次は実際にコンパイルをしてみます。

cli

npm経由でrejsコマンドをインストールできます。

使い方は、-hオプションで見ることができます。

基本的な使い方は、rejs [options] [files ...] となっており、-o オプションで書き出すファイル名を指定することができます。

今回は、distディレクトリにXmasPresent.jsとして書き出せばいいので、下記のコマンドを実行すれば完了です。

Gruntプラグイン

次に、rejsの作者が開発しているGruntプラグインを用いたコード例です。

URL: https://github.com/Moncader/grunt-rejs

Gruntfile.js:

registerTaskを省略していますが、

grunt.configのプロパティを使いタスクを走らせてビルドしてみましょう。

これで、dist/XmasPresent.jsがビルドされます。

gulpプラグイン

最後に、@kuuが開発しているgulpプラグインを用いたコード例を紹介します。

URL: https://github.com/kuu/gulp-rejs

READMEを参考に、gulpfileを書きます。

gulpfile.js:

コマンドを実行してビルドしてみましょう。

やっぱりgulpfile見やすくて良いですね。

Code example on Github

これにてrejsの紹介はおしまいです!

下記URLにて本エントリに出てくるソースコード一式を公開してあるので、

ご自由にご利用くださいm(_ _)m

 

URL: https://github.com/watilde/rejs-example

 

あとがき

今後もグリーでは、社内で開発したライブラリを公開したりOSSコミュニティに貢献していきます。
クリスマスを待つ間、引き続きGREE Advent Calendar 2014をお楽しみ頂ければ幸いです!
明日はマーケティング部の戸井田明俊さんと情報システム部の亀井利光さんです。


 

参考資料

記事の補足として、記事内で出てきたツールやライブラリのURLと用語の説明を載せておきます。併せてご覧頂ければと思います。

URL(s)

用語

  • Vanilla JS Module: グローバル・ネームスペースを介してシンボルをexport/importする従来のJavaScriptコード