gulpでbrowserifyを使う

[gulp](http://gulpjs.com/)で[browserify](link:http://browserify.org/)を使って、Web開発で使用するモジュールを管理します。ただ同じことはwebpackでもできるので、自分はほとんどwebpackを使っています。



## browserify

以前はgulp-browserifyを使っていたんだけれども、[BlackList](https://github.com/gulpjs/plugins/blob/master/src/blackList.json)に含まれていて推奨されない方法とされているので、直接browserifyを使います。

gulpのレシピにある[Browserify + Uglify2 with sourcemaps](https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md)あたりが参考になりそうです。

### インストール

```ps1
npm init
npm install gulp bower debowerify browserify vinyl-transform --save-dev
```

ウェブ用のパッケージは[bower](http://bower.io/)でしか管理されていないこともあるので一応いれておきました。[debowerify](https://github.com/eugeneware/debowerify)はbowerで取得したファイルを簡略な指定によってbrowserifyで使うためのもので`package.json`に以下を追記する必要があります。

```json
"browserify": {
  "transform": [
    "debowerify"
  ]
},
```

bowerのファイルがプロジェクトのルート直下から変更したい場合には、`.bowerrc`を作成してディレクトリの指定をします。

```json
{
  "directory": "/app/bower_components"
}
```



### gulpfile.js

```js
var gulp = require('gulp');
var transform = require('vinyl-transform');
var browserify = require('browserify');

gulp.task('js', function() {
  return gulp.src('app/scripts/main.js')
    .pipe(transform(function(filename) {
      return browserify(filename, {
        debug: true
      }).bundle();
    }))
    .pipe(gulp.dest('dist'));
});
```

`vinyl-transform`は`bundle`の返すファイルストリームをnpmで使用されているvinylに変換するために使われています。



## watchify

browserifyで`watch`していると、ファイルの増加によってその処理時間もどんどん増えてくので`watch`のときにはWatchifyで差分コンパイルをします。

* [Fast browserify builds with watchify](https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md)
* [watchify を試す | アカベコマイリ](http://akabeko.me/blog/2015/02/watchify/)

上記のサイトを参考にしました。

### インストール

browserifyがインストール済みであることを想定しています。

```ps1
npm install watchify vinyl-source-stream gulp-util --save
```

`gulp-util`は必須ではないんだけど、出力されるログは色がついていたほうがわかりやすいので使いました。

### gulpfile.js

```js
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify   = require('watchify');
var $ = require('gulp-load-plugins')();

gulp.task('browserify', function() {
  return compile(false);
});

gulp.task('watchify', function() {
  return compile(true);
});

function compile(watch) {
  var bundler = null;
  var option = {
    debug: true
  };

  if (watch) {
    option.cache = {};
    option.packageCache = {};
    option.fullPaths = true;
    bundler = watchify(browserify(path.js, option));
  } else {
    bundler = browserify(path.js, option);
  }

  function bundle() {
    return bundler
      .bundle()
      .on('error', $.util.log.bind($.util, 'Browserify Error'))
      .pipe(source('main.js'))
      .pipe(gulp.dest(path.dist));
  }

  bundler.on('update', bundle);
  bundler.on('log', function(msg) {
    $.util.log('Finished', '\'' + $.util.colors.cyan('watchify') + '\'', msg);
  });

  return bundle();
}

// watchifyは監視しなくていい
gulp.task('watch:js', ['watchify']);
```



## 参照文献

* [angular-gulp-browserify-seed](https://github.com/mjhea0/angular-gulp-browserify-seed)
* [javascript - Can&#39;t get external library with browserify and debowerify - Stack Overflow](http://stackoverflow.com/questions/25088406/cant-get-external-library-with-browserify-and-debowerify)
* [gulp と browserify と vinyl の話](http://umai-bow.hateblo.jp/entry/2014/10/08/002235)
* [watchify を試す | アカベコマイリ](http://akabeko.me/blog/2015/02/watchify/)