browserifyで始めるjavascriptモジュールのインテリジェンスな開発

javascriptモジュール開発中に色々困っていたことを解決するために、[browserify](http://browserify.org/)というのを使ってみた。

## 作ろうとしているモジュール
広告配信用モジュール
第三者ページに提供するため、jqueryなど既存ページに影響を与える可能性があるモジュールは、
使用できず、生でコードを書いています。

## 困ったこと一覧
#### 可読性
1ソースでjavascriptモジュールを作成していたため、だんだんソースコードが長くなり、
処理を追うのが大変になってきた。

#### 保守性
メンテナンスをする場合に、間違った箇所を修正したり、
修正箇所が足りなかったりと色々問題が起きそうな気がしてきた。

#### テスト
保守性とかぶる部分があるが、修正後のテストを自動化させたいが、
1ソースなので、自動化に工数がかかる。

## browserifyを知ったきっかけ
上記のような問題を解決するためのソリューションを探していたところ、
gruntとrequirejsを使えばうまくいくらしいことを発見。

ただ、よくよく調べると、結合したjavascriptファイルに
`require`の文言が残ってしまい、ページに組み込む際に、
`<script src="require.js"></script>`
`require.js`を読み込む必要があるみたいで、既存ページに影響を与える可能性があるため、
使うのを断念しました。

※さらに調べた結果、[almond](https://github.com/jrburke/almond)というモジュールを合わせて使うと、`require`の部分を解決して、1ファイルにできるらしいです。

困っていたところで、目の前にいた超人エンジニアの人に聞いてみたところ、
gruntとrequirejsはもう古く、時代は、gulpとbrowserifyだと言われたのをきっかけに、
browserifyを調べてみました。

## browserifyとは？
簡単に言うと、フロントサイド向けのrequirejsらしいです。
確かにrequirejsは、サーバサイド向けぽいです。

できることは、requirejsと大体一緒で、フロントサイド向けみたいな感じらしいです。
以下ページから参照させていただきました。

> [browserify をはじめてみる](http://please-sleep.cou929.nu/trying-browserify.html)
> Node.js の require をブラウザ上でも使えるようにするもの、ということでいいみたい。

> [browserify-handbook](https://github.com/substack/browserify-handbook)
> 公式のドキュメントです。

## 使用例
以下のようなjavascriptを使用する例を考えました。

``` math.js 
(function(){
	// 計算結果格納用変数
	var result = 1;
	
	// ローカル計算用メソッド
	var method = {
		// 掛け算
		multiplication : function(a){
			return result * a;
		},
		// 足し算
		addition : function(b){
			return result + b;
		}
	};

	// onload時のログ出力メソッド
	var log = function(){
		console.log("on load");
	};

	// resize時のログ出力メソッド
	var resize = function(){
		console.log("on resize");
	};

	// グローバル計算用メソッド
	window.MATH = window.MATH || {
		// 掛け算
		multiplication : function(num){
			result = method.multiplication(num);
			console.log(result);
		},
		// 足し算
		addition : function(num){
			result = method.addition(num);
			console.log(result);
		}
	};

	// リスナー
	window.addEventListener("load",log,false);
	window.addEventListener("resize",resize,false);
})();
```

``` Browser.Console
MATH.addition(10);
11
MATH.multiplication(10);
110
```
ソースは[こちら](https://github.com/takuhou/math-browserify/blob/master/math.js)。

計算機能とリスナーでログを出力する機能を有しています。

#### browserifyのインストール
`npm install -g browserify`

#### ファイル分割&結合してみる
1ソースだったファイルを、メソッド単位で分けてみることにする。

計算結果格納変数(result.js)
ローカル計算メソッド(local-method.js)
ログ出力メソッド(log.js)
グローバル計算メソッド(global-method.js)
→[ここらへん](http://www.mattburkedev.com/export-a-global-to-the-window-object-with-browserify/)を参考にしてみました。
リスナー(listener.js)

それに伴い、ログ出力メソッドをまとめてみる。

ソースは[こちら](https://github.com/takuhou/math-browserify/tree/master/v1)

ファイルを結合してみる。
`browserify ./v2/src/* -o ./v2/build/math.js`

動かしてみる。

``` Browser.Console
MATH.addition(10);
11
MATH.multiplication(10);
12
```

計算結果を格納しているresult変数がうまく動いてないです。

#### resultの動きを調べてみる
1ソースの時は、result変数がプログラム内のグローバル変数として、存在していたが、
ファイルを分割したことにより、result変数を宣言したモジュールをそれぞれの変数で読み込んでいる。

console.logを仕込み、result変数の推移を見てみた。

```Frist.step
MATH.addition(10);
global-method.js:Result:1
local-method.js:Result:1
結果：11
```

```Second.step
MATH.addition(10);
global-method.js:Result:11
local-method.js:Result:1
結果：11
````

local-method.jsのresult変数が1のままで、
global-method.jsのresult変数の保存領域が、別になっているぽいです。

#### result.jsを修正してみる

修正したソースは[こちら](https://github.com/takuhou/math-browserify/tree/master/v2)。

修正箇所としては、
result変数を扱うためのsetterとgetterの追加をしました。

それに伴い、他のところで使っているresultの処理も変更しました。

``` Browser.Console
MATH.addition(10);
11
MATH.multiplication(10);
110
```

元のmath.jsと同様の動きになりました。

## 感想
元のソースの書き方がイケてないと、分割した時に修正する必要がありますね。
特にプログラム内で共有する変数がある場合など。

`require`の挙動などまだ調べないといけない部分があるので、調べたら追記しておきます。
後は、browserifyと合わせて使われる[gulp](http://gulpjs.com/)についても調べてみます。

メンテナンスやテストを自動化するために、一つ一つのモジュールを小さく開発することが、
求められる昨今なので、browserifyやgulpなどを合わせて、インテリジェンスな開発を行えることが、
開発者のスキルとして必須なものになってきそうですね。