Grunt管理されたjQueryでコードハック 〜 JSおくのほそ道 #010

こんにちはほそ道です。
今回は「jQueryコードハックするならこの仕組み知っとくといいかも」というネタを紹介します。

[目次はこちら](http://qiita.com/setzz/items/ad9a9c99a4fda041a563)

# jQueryの取得先

jQueryコードを入手する場合さまざまなルートがあります
- [公式サイトからダウンロード](http://jquery.com/download/)
- [CDNにホストされたjQueryをダウンロード](https://developers.google.com/speed/libraries/devguide?hl=ja#jquery)
- [githubからclone](https://github.com/jquery/jquery)

今回は３番目のgithub上のjQueryを取り上げます。
こちらはjQueryそのものの開発プロジェクトですね。
Gruntが採用されていてjQueryカスタムビルドを行ったり、
テストを実行する事も出来ます。(コミッターになるなら必須ですね)

Gruntわかんねーという方は[以前まとめております](http://qiita.com/setzz/items/3159a0fe1d0fcda58c3e)のでご一読くださいませ。

# github上のjQuery取得とシンプルなビルド

ソースコードの取得とjQueryビルドは下記のように行います。

## 2系のビルド
```bash:bash
git clone git://github.com/jquery/jquery.git
cd jquery
npm run build
```

## 1系のビルド
```bash:bash
git clone https://github.com/jquery/jquery.git -b 1.9-stable
cd jquery
npm install && grunt
```

現在は2系がmasterブランチで、1系は1.9-stableというブランチとなっているようです。
cloneしたディレクトリにはsrcディレクトリが存在し、
その中にビルドで組み上げられるモジュール群が格納されています。
npmコマンドでdistディレクトリが生成され、その中に結果ファイルとして
dist/jquery.jsや、ミニファイされたdist/jquery.min.jsが出力されます。

# カスタムビルド
## 除外ビルド
先ほどのビルド方法で組み上げるとデフォルトで設定されたモジュール群が
すべてdistディレクトリのファイルに含まれる事になります。
ちなみに２系のdist/jquery.jsは9191行ありました。でかいな。。

ここでひとつREADMEにかいてあった **カスタムビルド** を試してみます。
下記コマンドの実行でビルド結果からajax系のモジュールを除外します。

```bash:bash
grunt custom:-ajax
```

これによってajax系のモジュールが除外され、
dist/jquery.jsは8010行までコード量が減りました。
ajaxの機能を全く使用しない場合は可読性の向上とファイルサイズの縮小が見込めます。

```bash:bash
grunt custom:-ajax,-css
```

また、上記のように複数のモジュールを除外する事も出来ます。

もうひとつのメリットとして除外を行うと、
実際に除外されたファイルの一覧がコンソールに出力されます。
これによって、ファイル/機能のグルーピングもある程度把握できます。


## カスタムビルドの裏側

カスタムビルドはcustomタスクにマイナス記号でモジュール名を与えると除外されるという仕組みですが、
裏側では何をやっているのでしょう？
Guntfile内に`grunt.loadTasks( "build/tasks" );`という記述があります。
実際に`build/tasks/build.jsというファイルがあり、
buildタスクやcustomタスクが定義されていました。
下記はcustomタスクの内容です。

```js:build/build.js
grunt.registerTask( "custom", function() {
  var args = this.args,
  modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";

  grunt.log.writeln( "Creating custom build...\n" );
  grunt.task.run([ "build:*:*" + (modules ? ":" + modules : ""), "uglify", "dist" ]);
});
```

buildタスクに`:*:*`を加えて、さらにコマンド引数の`,`を`:`にして`:module1:module2`を与えて実行していますね。
ということは。。

```bash:bash
# さっきの
grunt custom:-ajax,-css
# こういうのもできる
grunt build:*:*:-ajax:-css
```

上記の様にしてもコマンドラインから実行可能ということですね。
ちゃんとdist/jquery.jsに除外が反映されているようです。

ちなみに、ソースコード内のコメントから`:*`をひとつだけ置くとemptyなjsを生成し
マイナス記号をプラス記号に変えると除外から追加に変わるよという記述を発見。
下記のようなコマンドを打つと最小構成が作れるんじゃないか！？

```bash:bash
# ところがバッテン。。。
grunt build:*:+core:+selector
```

コマンドが成功してそれっぽいjquery.jsが出力されました、が、、
残念ながらjQueryオブジェクトが生成されず、defineメソッド無いよというエラーが出てしまいました。。
とりあえず諦めます。。

## 最小構成ビルド

というわけで真の最小構成ビルドは除外によって作成するようです。
ちなみに除外可能なモジュールは[README](https://github.com/jquery/jquery/blob/master/README.md)に記載されてます。
※ブラウザ向けの実行時は`exports/global`を除外すると$/jQuery変数が使用できなくなるようですので含めておきます。

```bash:bash
# 最小構成ビルドです
grunt custom:-ajax,-css,-deprecated,-dimensions,-effects,-event,-event/alias,-offset,-wrap,-core/ready,-deferred,-exports/amd,-sizzle
```

ちなみにdist/jquery.jsの行数は3224行。
ほそ道的にはもっと小さくしたいですが、
これだけでも基本機能のコードハックは相当やりやすくなったはずです。

# まとめ
github上のjqueryを使う事で以下のようなコードハック上の利点が考えられます。

- カスタムビルドを行う事で組み上げられたjQueryがシンプルな構成になる。
- src上の分割されたモジュールを追う事で要点がつかみやすくなる。 

今回は以上です。
次回はjQueryの根幹部のひとつ、[CSSセレクタの仕組み](http://qiita.com/setzz/items/25064020f199e35d65db)を調べていこうと思います。