browserify で複数の CoffeeScript を一つにまとめる


[この前 Grunt で試した事](http://qiita.com/akishin/items/8454786dc12e534531be "Grunt で複数の CoffeeScript を一つの無名関数内にまとめる") と同じような事を browserify を使って試してみた。

### 公式

Browserify
http://browserify.org/

substack/node-browserify
https://github.com/substack/node-browserify

### インストール

browserify 本体はグローバルにインストール。
これで `browserify` コマンドが使えるようになる。

```shell-session
% sudo npm install -g browserify
% browserify --version
6.2.0
```

スクリプト配置用に適当にディレクトリを作成して package.json を作成。

```shell-session
% mkdir -p browserify-test/{src,dest} && cd browserify-test
% npm init
```

browserify の --transform(-t) オプションで CoffeeScript をコンパイル出来るようにするために coffeeify をインストール。

```shell-session
% npm install coffeeify --save-dev
```

### スクリプト作成

以下のような感じでスクリプトを作成した。

```coffee:src/foo.coffee
class Foo
  name: ->
    'Foo'
module.exports = Foo
```

```coffee:src/bar.coffee
class Bar
  name: ->
    'Bar'
module.exports = Bar
```

突然出てきた module.exports については多分以下辺りを読んで書いてあるような理解でいいんだと思う。
要は Node.js の仕組み。

module.exports
http://nodejs.jp/nodejs.org_ja/docs/v0.10/api/modules.html#modules_module_exports

Node.jsのmoduleの書き方の基本: 別のファイルのオブジェクトや関数をrequireして使う方法 - memo.yomukaku.net
http://memo.yomukaku.net/entries/jbjiYnP

これらを使う main.coffee は以下のような感じ。
使いたいファイルを明示的に `require` する。

```coffee:src/main.coffee
Foo = require('./foo.coffee')
Bar = require('./bar.coffee')

foo = new Foo()
bar = new Bar()

console.log(foo.name())
console.log(bar.name())
```

### browserify を実行

これで準備は出来たので、`browserify` コマンドを実行する。
--transform(-t) オプションに `coffeeify` を指定することで coffee スクリプトから js に変換してくれる。

```shell-session
% browserify -t coffeeify src/main.coffee > dest/bundle.js
```

実行してみる。

```shell-session
% node dest/bundle.js
Foo
Bar
```

上手く動いてる。
出力された js は以下のようなものだった。

```javascript:dest/bundle.js
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var Bar;

Bar = (function() {
  function Bar() {}

  Bar.prototype.name = function() {
    return 'Bar';
  };

  return Bar;

})();

module.exports = Bar;



},{}],2:[function(require,module,exports){
var Foo;

Foo = (function() {
  function Foo() {}

  Foo.prototype.name = function() {
    return 'Foo';
  };

  return Foo;

})();

module.exports = Foo;



},{}],3:[function(require,module,exports){
var Bar, Foo, bar, foo;

Foo = require('./foo.coffee');

Bar = require('./bar.coffee');

foo = new Foo();

bar = new Bar();

console.log(foo.name());

console.log(bar.name());



},{"./bar.coffee":1,"./foo.coffee":2}]},{},[3]);
```

### Grunt から browserify を使う

grunt-browserify を使って grunt から browserify を実行してみる。

jmreidy/grunt-browserify
https://github.com/jmreidy/grunt-browserify

インストール。

```shell-session
npm install grunt grunt-browserify --save-dev
```

以下のような内容の Gruntfile.js を作成。

```javascript:Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    browserify: {
      dist: {
        files: {
          'dest/bundle.js': ['src/*.coffee'],
        },
        options: {
          transform: ['coffeeify']
        }
      }
    }
  });
  grunt.loadNpmTasks('grunt-browserify');
  grunt.registerTask('default', ['browserify']);
};
```

grunt 実行。

```shell-session
% grunt
Running "browserify:dist" (browserify) task

Done, without errors.
```

生成された bundle.js を実行してみる。

```shell-session
% node dest/bundle.js
Foo
Bar
```

問題なく動作した。
ついでに適当な HTML ファイルを作成して読み込んでみる。

```html
<html>
  <head>
    <title>Hello, browserify</title>
    <script src="dest/bundle.js"></script>
  </head>
  <body>
    <h2>Hello, browserify</h2>
  </body>
</html>
```

ブラウザで開いてデベロッパーツールなどで console を確認するとコマンドラインで実行した時と同じ出力が得られた。

元々 Node.js のライブラリをブラウザ上で動かすためのツールということもあるしもっとちゃんと Node.js の作法とかを知ってた方が良さそうな気もするけど、それにしても簡単で便利で良さそう。

### 参考

Browserifyの使い方について調べてみた - yutaponのブログ
http://yutapon.hatenablog.com/entry/2014/03/09/205231

Gruntでbrowserify使ってCoffeescriptをコンパイルする。 ::: Toro_Unit
http://www.torounit.com/blog/2014/08/05/1782/