browserifyユーザーに向けて

このサイトは作成途中のものを公開しています。 また、Webpackのバージョンが1.13.0の頃に作成されたものですが、2017年2月現在Webpackは1系を非推奨として2の使用を勧めています。

使用方法

browserifyのように、webpackはアプリケーションのnodeスタイルのrequire()呼び出しを全て解析し、 <script>タグを使用してブラウザへ提供することが出来るバンドルを構築します。

このように実行していたことを、

$ browserify main.js > bundle.js

次のように実行することになります。

$ webpack main.js bundle.js

webpackは標準出力(stdout)を書き出しません。 ファイル名の指定が必要になります。 browserifyと違って標準出力が書き出せないのは、出力ファイルが複数になることがあるためです。

最良の方法はwebpack.config.jsファイルに設定を書くことです。 このファイルはランタイムの実行時に、カレント・ディレクトリから読み込まれます。

そのため次のbrowserifyの実行は、

$ browserify --entry main.js --outfile bundle.js

webpackの設定で次のように書くことが出来ます。

module.exports = {
    entry: "./main.js",
    output: {
        filename: "bundle.js"
    }
}

注意: webpack.config.jsは設定をexportする必要があり、 上記の例ではmodule.exports = {...}がそれに該当します。

outfile

もし出力ファイルを別のディレクトリにしたい場合は、次のように指定します。

# browserifyの場合
$ browserify --outfile js/bundle.js
// webpackの設定
{
    output: {
        path: path.join(__dirname, "js"),
        filename: "bundle.js"
    }
}

entry

# browserifyの場合
$ browserify --entry a.js --entry b.js
// webpackの設定
{
    entry: [
        "./a.js",
        "./b.js"
    ]
}

transform

browserifyはプリプロセス・ファイルの作成に、トランスフォーム(transform)を使用します。 対してwebpackはローダー(loader)を使用します。 ローダーは引数としてソースコードを受け取り、変更されたソースコードを返す関数です。 node.jsで実行されるトランスフォームのように、チェーンと非同期が可能です。

ローダーはクエリー文字列による追加のパラメーターを取得することが出来ます。 トランスフォームはpackage.json内で指定することが出来ます。 browserifyは設定がされたトランスフォームを各モジュールに適用します。 webpackでは正規表現によって選択したモジュールに設定を適用することが出来ます。 一般的には、webpack.config.js内でローダーが指定されます。

# browserifyの場合
$ browserify --transform coffeeify
// webpackの設定
{
    module: {
        loaders: [
            { test: /\.coffee$/, loader: "coffee-loader" }
        ]
    }
}

注意: transform-loaderを使用して、 webpackでbrowserifyを使用することも可能です。

debug

# browserifyの場合
$ browserify -d
# インラインのソースマップ(SourceMaps)を追加
# webpackの場合

$ webpack --devtool inline-source-map
# インラインのソースマップ(SourceMaps)を追加

$ webpack --devtool source-map
# 別ファイルのソースマップ(SourceMaps)を発行

$ webpack --devtool eval
# eval内でソースのURL(SourceUrls)を発行(高速)

$ webpack --devtool eval-source-map
# eval内でインラインのソースマップ(SourceMaps)を発行

$ webpack --debug
# ソースに、より多くのデバッグ情報を追加

$ webpack --output-pathinfo
# ソースコードへ、パスについてのコメントを追加
# (devtoolを使用していない、またはevalのdevtoolを使用している場合に便利)

$ webpack -d
# webpack --devtool source-map --debug --output-pathinfo の実行と等価

extension

# browserifyの場合
$ browserify --extension coffee
// webpackの設定の場合
{
    output: {
        library: "MyLibrary",
        libraryTarget: "umd"
    }
}
# webpackの実行の場合
$ webpack --output-library MyLibrary --output-library-target umd

standalone

# browserifyの場合
$ browserify --standalone MyLibrary
{
    output: {
        library: "MyLibrary",
        libraryTarget: "umd"
    }
}
// webpack --output-library MyLibrary --output-library-target umd

ignore

# browserifyの場合
$ browserify --ignore file.js
//webpackの設定
{
    plugins: [
        new webpack.IgnorePlugin(/file\.js$/)
    ]
}

node globals

nodeのグローバルな変数とオブジェクトに関する設定です。

# browserifyの場合
$ browserify --insert-globals
$ browserify --detect-globals

これらのnodeのグローバルな変数とオブジェクトを、個別に有効/無効を設定することが出来ます。

// webpackの設定
{
    node: {
        filename: true,
        dirname: "mock",
        process: false,
        global: true
    }
}

ignore-missing

# browserifyの場合
$ browserify --ignore-missing

webpackは必要な依存性が見つからない場合は、エラーを出力しますが、バンドルのビルドを失敗扱いにはしません。 これらのエラーを無視するかしないかは、開発者に委ねられます。 ランタイム時にはエラーがスローされます。

noparse

$ browserify --noparse=file.js
module.exports = {
    module: {
        noParse: [
            /file\.js$/
        ]
    }
};

build info

$ browserify --deps
$ browserify --list
$ webpack --json

external requires

webpackはexternal requiresをサポートしないため、 他のスクリプトへのrequireの公開が出来ません。 単純にページ上の全てのスクリプトでwebpackを使用するか、次のような対応を行うかになります。

{
    output: {
        library: "require",
        libraryTarget: "this"
    }
}
// entry point
module.exports = function(parentRequire) {
    return function(module) {
        switch(module) {
        case "through": return require("through");
        case "duplexer": return require("duplexer");
        }
        return parentRequire(module);
    };
}(typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : function() {
    throw new Error("Module '" + module + "' not found")
});

multiple bundles

browserifyを使用して、複数のページ上のバンドルで連携することが出来る、共通のバンドルを作成することが可能です。 これらのバンドルを生成するには、--exclude、または-xオプションを使用して、共通するものを抜き取る必要があります。 下記は、browserifyのREADMEからの例になります。

$ browserify -r ./robot > static/common.js
$ browserify -x ./robot.js beep.js > static/beep.js
$ browserify -x ./robot.js boop.js > static/boop.js

webpackは複数ページ・コンパイル(multi-page compilation)をサポートし、 共通モジュールを自動的に抜き出すプラグインも用意されています。

var webpack = require("webpack");
{
    entry: {
        beep: "./beep.js",
        boop: "./boop.js",
    },
    output: {
        path: "static",
        filename: "[name].js"
    },
    plugins: [
        // ./robotは自動的に共通モジュールを検知し、抜き出します。
        new webpack.optimize.CommonsChunkPlugin("common.js")
    ]
}
<script src="common.js"></script>
<script src="beep.js"></script>

API

下記のように、webpackのAPIに設定オブジェクトを渡すことが出来るので、 不必要にオプションを覚える必要はありません。

var webpack = require("webpack");

webpack({
    entry: "./main.js",
    output: {
        filename: "bundle.js"
    }
}, function(err, stats) {
    err             // => fatal compiler error (rar)
    var json = stats.toJson() // => webpack --json
    json.errors     // => エラーの配列
    json.warnings   // => 警告の配列
});

3rdパーティ対応表

browserify webpack
watchify webpack --watch
browserify-middleware webpack-dev-middleware
beefy webpack-dev-server
deAMDify webpack
decomponentify component-webpack-plugin
ソース(source)の変換 ローダー一覧、transform-loader

 Back to top

© 2010 - 2017 STUDIO KINGDOM