gulpを使ったJavaScript(とCoffeeScript)のビルド


ビルドが必要なほど大きいものを書いていないけど今後必要になりそうなので試してみた

## 前提

- npm導入済

## browserifyとgulpをインストール

```
$ npm install -g browserify 
$ npm install -g gulp
```

## プロジェクトの作成と必要なライブラリの導入

```
$ mkdir build_test
$ cd build_test/
$ mkdir build
$ mkdir src
$ npm init
$ npm install --save-dev gulp browserify coffee-script coffeeify vinyl-souce-stream
```

## JavaScriptのビルド

下記のようなjsをビルドする。

```js:src/foo.js
function Foo(x, y){
  this.x = x;
  this.y = y;
}

Foo.prototype = {
  sum: function() {
    return this.x + this.y;
  }
};

module.exports = Foo;
```

```js:src/sample.js
var Foo = require('./foo');

var foo = new Foo(10, 20);

console.log(foo);
console.log(foo.sum());
```

用意する `gulpfile.coffee` はこんな感じ。

```coffee:gulpfile.coffee
gulp = require 'gulp'
source = require 'vinyl-source-stream'
browserify = require 'browserify'

gulp.task 'build', ->
  browserify
      entries: ['./src/sample.js']
    .bundle()
    .pipe source 'bundle.js'
    .pipe gulp.dest 'build'

gulp.task 'default', ['build']
```

ビルドを実行

```
$ gulp
[14:19:01] Requiring external module coffee-script/register
[14:19:01] Using gulpfile ~/build_test/gulpfile.coffee
[14:19:01] Starting 'build'...
[14:19:01] Finished 'build' after 81 ms
[14:19:01] Starting 'default'...
[14:19:01] Finished 'default' after 23 μs
```

実行してできあがる `bundle.js` はこうなる。

```js: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){
function Foo(x, y){
  this.x = x;
  this.y = y;
}

Foo.prototype = {
  sum: function() {
    return this.x + this.y;
  }
};

module.exports = Foo;

},{}],2:[function(require,module,exports){
var Foo = require('./foo');

var foo = new Foo(10, 20);
console.log(foo);
console.log(foo.sum());

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

## CoffeeScriptのビルド

```coffee:Bar.coffee
class Bar
  constructor: (x, y) ->
    @x = x
    @y = y

  sum: ->
    @x + @y

module.exports = Bar
```

```coffee:example.coffee
Bar = require './Bar'

bar = new Bar(10, 20)

console.log(bar)
console.log(bar.sum())
```

用意する `gulpfile.coffee`

```coffee:gulpfile.coffee
gulp = require 'gulp'
source = require 'vinyl-source-stream'
browserify = require 'browserify'

gulp.task 'build', ->
  browserify
      entries: ['./src/example.coffee']
      extensions: ['.coffee']
    .transform 'coffeeify'
    .bundle()
    .pipe source 'bundle2.js'
    .pipe gulp.dest 'build'

gulp.task 'default', ['build']
```

ビルドを実行

```
$ gulp
[14:13:48] Requiring external module coffee-script/register
[14:13:48] Using gulpfile ~/build_test/gulpfile.coffee
[14:13:48] Starting 'build'...
[14:13:48] Finished 'build' after 99 ms
[14:13:48] Starting 'default'...
[14:13:48] Finished 'default' after 21 μs
```

できあがったbundle2.js

```js:build/bundle2.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(x, y) {
    this.x = x;
    this.y = y;
  }

  Bar.prototype.sum = function() {
    return this.x + this.y;
  };

  return Bar;

})();

module.exports = Bar;


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

Bar = require('./Bar');

bar = new Bar(10, 20);

console.log(bar);

console.log(bar.sum());


},{"./Bar":1}]},{},[2]);

```

### ファイルの変更を監視してビルド

`gulpfile.coffee` に以下を追加する。
`src/` 以下の.coffeeファイルが変更されると `build` が実行される。

```
gulp.task 'watch', ->
  gulp.watch 'src/*.coffee', ['build']
```

## 参考

[gulpとBrowserifyでJSをビルドしてみた - Qiita](http://qiita.com/seanchas_t/items/96fbb63e5fe36f94a42e)
[Browserify + GulpでクライアントのJavaScript / CoffeeScriptでrequire | EasyRamble](http://easyramble.com/browserify-gulp-require.html)
[npm とか bower とか一体何なんだよ！Javascript 界隈の文脈を理解しよう - Qiita](http://qiita.com/megane42/items/2ab6ffd866c3f2fda066)