CLOVER🍀

That was when it all began.

Broserifyを使ってJavaScriptのビルド/minify(+Bower)

先ほどwebpackで書いたエントリ、

webpackを使ってJavaScriptのビルド/minify(+Bower) - CLOVER

のBrowserify版です。

やりたいことは同じで、

  • 複数のJavaScriptをまとめたい
  • まとめたJavaScriptはminifyしたい
  • SourceMapも作成したい
  • Bowerを使って依存関係も解決したい

というもの。先ほどはこれをwebpackで書きましたが、今度はBrowserifyで書いてみます。

Browserify

Bowerで引き込むライブラリは、同じくjQueryとします。

※最後に、Bowerなし版も付けています

セットアップ

まずは、以下のコマンドを実行。

$ npm init
$ npm install -g gulp browserify bower
$ npm install gulp bower debowerify browserify bower-resolve gulp-uglify gulp-sourcemaps vinyl-source-stream vinyl-buffer --save-dev
$ bower init
$ bower install jquery --save

バージョン情報。

$ node --version
v4.1.0
$ npm --version
2.14.3
$ bower --version
1.5.2

対象のスクリプトとHTML

基本的に、webpackの時と同じです。ちょっとメッセージが異なるくらい。

エントリポイント。
scripts/main.js

var $ = require("jquery");
var init = require("./init");
var messages = require("./messages");

init();

$(function() {
    $("#show-message1").on("click", function() {
        $("#message1").text(messages.get("message1"));
    });
    $("#show-message2").on("click", function() {
        $("#message2").text(messages.get("message2"));
    });
});

scripts/init.js

var $ = require("jquery");
module.exports = function() {
    $(function() {
        $("#title").text("BrowserifyとBowerのテストです");
    });
};

scripts/messages.js

module.exports = {
    msgs: {
        "message1": "Hello Workd",
        "message2": "こんにちは、世界"
    },
    get: function(id) {
        return this.msgs[id];
    }
};

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Browserify &amp; Bower テストページ</title>
</head>
<body>
  <h1 id="title"></h1>
  <div>
    <input id="show-message1" type="button" value="メッセージ1を表示">
    <input id="show-message2" type="button" value="メッセージ2を表示">
  </div>
  <span id="message1"></span><br>
  <span id="message2"></span><br>
  <script type="text/javascript" src="dist/scripts/app.js"></script>
</body>
</html>

gulpfile.jsを書く

webpackの時とは異なり、こちらはgulpfile.jsだけで完結します。
gulpfile.js

var gulp = require("gulp");
var browserify = require("browserify");
var bowerResolve = require("bower-resolve");
var source = require("vinyl-source-stream");
var buffer = require("vinyl-buffer");
var uglify = require("gulp-uglify");
var sourcemaps = require("gulp-sourcemaps");

gulp.task("javascript", function() {
    bowerResolve.init(function() {
        browserify({
            entries: "./scripts/main.js"  // ビルド対象のファイル
            // debug: true  // trueにすると、//# sourceMappingURL=data:application/json;charset:utf-8;base64,〜でsourcemapが出力される
        })
            .require(bowerResolve("jquery"), { expose: "jquery" }) // Bowerのファイルを、Browserifyでも使えるように
            .bundle()
            .pipe(source("app.js"))  // ビルド後のファイル名
            .pipe(buffer())
            .pipe(sourcemaps.init({loadMaps: true}))  // sourcemap作成
            .pipe(uglify())  // minify
            .pipe(sourcemaps.write("./"))
            .pipe(gulp.dest("./dist/scripts/"));  // 生成先の指定
    });
});

gulp.task("default", ["javascript"]);

BowerとBrowserifyの組み合わせには、bower-resolveというものを使っています。

bower-resolve - npm

init後に

    bowerResolve.init(function() {

以下のように呼び出すことで、BrowserifyでビルドするJavaScript上でもBowerのファイルをrequireできるようになるみたいです。

            .require(bowerResolve("jquery"), { expose: "jquery" }) // Bowerのファイルを、Browserifyでも使えるように

minifyはgulp-uglifyで、SourceMapの作成はgulp-sourcemapsで行っています。

            .pipe(sourcemaps.init({loadMaps: true}))  // sourcemap作成
            .pipe(uglify())  // minify
            .pipe(sourcemaps.write("./"))

で、これらの間をつなぐのにvinyl-source-stream、vinyl-bufferが必要みたいです。

            .pipe(source("app.js"))  // ビルド後のファイル名
            .pipe(buffer())

参考)
Browserify + Uglify2 with sourcemaps

Browserify を使ってみる 2 – Source Map – アカベコマイリ

npmとbrowserifyを使ったクライアントサイドのウェブアプリ開発 | Web Scratch

Browserify + gulp-uglify で JS ファイルを連結 & minify – Gulp で作る Web フロントエンド開発環境 #3 – PSYENCE:MEDIA

Browserify: それはrequire()を使うための魔法の杖

gulpでbrowserifyを使う

Browserify を使ってみる – アカベコマイリ

gulpとBrowserifyでJSをビルドしてみた

Browserify + GulpでクライアントのJavaScript / CoffeeScriptでrequire | EasyRamble

実行

ここまでやったら、ビルド。

$ gulp
[16:41:28] Using gulpfile ~/xxxxx/gulpfile.js
[16:41:28] Starting 'javascript'...
[16:41:28] Finished 'javascript' after 1.23 ms
[16:41:28] Starting 'default'...
[16:41:28] Finished 'default' after 6.25 μs

同じく、ビルド後のファイルとSourceMapができていますと。

$ ls -l dist/scripts
合計 488
-rw-rw-r-- 1 xxxxx xxxxx  85334  921 16:41 app.js
-rw-rw-r-- 1 xxxxx xxxxx 409691  921 16:41 app.js.map

Bowerなし版

こちらも、Bowerなしでやれるそうな。セットアップ時のコマンドが以下の様になります。

$ npm init
$ npm install -g gulp browserify
$ npm install gulp browserify gulp-uglify gulp-sourcemaps vinyl-source-stream vinyl-buffer jquery --save-dev

debowerifyとbower-resolveを落として、jQueryを追加しました。

gulpfile.jsは、もっとすっきりします。
gulpfile.js

var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var buffer = require("vinyl-buffer");
var uglify = require("gulp-uglify");
var sourcemaps = require("gulp-sourcemaps");

gulp.task("javascript", function() {
    browserify({
        entries: "./scripts/main.js"  // ビルド対象のファイル
        // debug: true  // trueにすると、//# sourceMappingURL=data:application/json;charset:utf-8;base64,〜でsourcemapが出力される
    })
        .bundle()
        .pipe(source("app.js"))  // ビルド後のファイル名
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))  // sourcemap作成
        .pipe(uglify())  // minify
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest("./dist/scripts/"));  // 生成先の指定
});

gulp.task("default", ["javascript"]);