JavaScript
Node.js
webpack

Backpackについて調べた

お手伝いしているプロジェクトでBackpackなるものが使われており、はてな?と思ったので調べました。

Backpackとは?

https://github.com/jaredpalmer/backpack

Backpack is a minimalistic build system for Node.js projects.

Backpackは、Node.jsのプロジェクトの最小限のビルドシステムだぜ!とのことです。create-react-appやNext.jsにインスピレーションを得たようで、設定ファイルの記述や追加のnpmパッケージなしで、

  • Babelによるトランスパイルの実行。async/await、object rest spread、class propertiesなどの構文の利用
  • source-mapの対応(source-map-support)
  • nodemon的なファイル監視、再実行(Live Reloading)

が、出来るようです。内部ではwebpackを使っているため、webpackが分かるとカスタマイズしやすそう。Backend + webpack = Backpackという由来みたいです。

インストール

npmパッケージ名はbackpack-core。ドキュメントでは--saveyarn add backpack-core)でインストールしているが、用途的に--save-devで問題ないと思う。

# npmの場合
$ npm install --save-dev backpack-core

# yarnの場合
$ yarn add -D backpack-core

CLI

backpack-coreをインストールすると、backpackコマンドが使えるようになります。backpackコマンドには、

  • backpack or backpack dev
  • backpack build

の2種類のサブコマンドしかありません。とてもシンプル!

backpack or backpack dev

$ yarn backpack
# または
$ yarn backpack dev

開発モード。backpackまたは、backpack devを実行すると、src/index.jsをエントリポイントとして実行し、ファイルの監視を開始します。(↓の感じの画面)

image.png

backpack devで起動した場合は、__DEV__trueが入るので、開発モードかどうか判定したい場合はそれを使うとよい。__DEV__は、webpackのDefinePluginで定義されている。(ソース

if (__DEV__) {
  // backpack or backpack devで起動した場合
}

babelとwebpackの設定については、カスタマイズできるみたい。

Babelの設定のカスタマイズ

プロジェクトルートに.babelrcを置くだけ。Backpackの設定を踏襲したい場合は、presetsbackpack-core/babelを追加して、追加したいpresetやpluginをインストール、記述すればよい。

.babelrc
{
  "presets": [
    "backpack-core/babel",
    "stage-0",
    ...
  ]
}

backpack-core/babelbabel-preset-backpackを参照しているだけなので、babel-preset-backpackのindex.jsを見ると、元々どういう設定なのか把握できる。

webpackの設定のカスタマイズ

backpack.config.jsを作成し、そのファイルのwebpackフィールドに設定を変更する関数を追加する。

backpack.config.js
module.exports = {
  /**
   * config      -> Backpackのwebpack.config.js
   * options     -> envがあるだけのオブジェクト
   * options.env -> 'development' or 'production'
   * webpack     -> require('webpack')
   */
  webpack: (config, options, webpack) => {
    // カスタマイズする
    ...

    // カスタマイズした設定を返す
    return config;
  }
};

また、backpack.config.jsはBabelのトランスパイルの対象外なので、利用しているNode.jsで使えない構文は書かないように気をつける必要がある。実装を確認してみたが、backpack.config.jswebpackフィールド以外に設定できる項目がないっぽいです。

backpack build

$ yarn backpack build

プロダクション用のビルドを実行。src/index.jsをエントリポイントにしてバンドルしたファイルをbuild/main.jsに出力する。「npmパッケージを全部バンドルしたら大変なサイズにならんか?」と心配になったが、webpack-node-externalsというnpmパッケージによって、node_modules以下のファイルはwebpackのexternalsに指定されており、バンドル後のファイルには含まれない。ここにその設定が記述されているが、画像やCSSなどはホワイトリストに入っているので、webpackのloaderを駆使すればJSから操作できるようになりそう。

おわり

設定や使用方法が本当にミニマムで、すぐ理解できる。Backpack自体の実装もかなりミニマム&シンプルで、さらっと読める感じなので、Less configurationを突き詰め過ぎて裏で何やっているか分からん、みたいなことは起きない。(これからどんどん機能追加されて辛くなるかもしれないけど)
Node.jsのESのサポートがよくなってもFlowtypeなどを使いたい場合はBabelを入れることになるので、Babelを使うプロジェクトをさっと始めたい場合はかなりよいかもしれない。