Bowerをサクッと使うコマンド「onefile」を作った

`$ bower install jquery --save`のあと、公式のマニュアルやgithubのページを見て、目当てのコア・ファイルを探しに行くと思いますが、おっかなびっくり`<script>`や`<link>`を書き足す作業が非常に面倒です。

[gulpの書き方を覚えれば](http://qiita.com/59naga/items/02ba2963fd957ef6cf36)、この作業は軽減できますが、欲を言えばgulpfileめんどい。なので、`bower install jquery --save`の後に実行すると、コア・ファイルを連結して`.js`を吐き出す [onefile](https://github.com/59naga/onefile#readme) コマンドを作りました。

## 要件
`bower install`済みの`bower_components`と、`bower.json`を用意して、そのディレクトリに移動してください。

空のディレクトリから`angular-ui-router`を用意する場合は

```bash:cmder
mkdir hoge
cd hoge

bower init # yes, yes, yes...
bower install angular-ui-router --save
tree . -L 2
# .
# ├── bower.json
# └── bower_components
#     ├── angular
#     └── angular-ui-router
```

上記のようにします。

# インストール
`bower`同様に、`onefile`を`npm`からグローバルインストールします。

```bash:cmder
npm install onefile --global
onefile -V
# 0.3.1
```

# 使用法
`onefile`コマンドで標準出力、`onefile -o pkgs`コマンドで外部ファイルへ出力します。

```bash:cmder
onefile > pkgs.js
# or
onefile -o pkgs
# Found:
#       1.06 MB bower_components/angular/angular.js
#     162.91 kB bower_components/angular-ui-router/release/angular-ui-router.js
# Yield:
#       3.13 MB pkgs.js
```

`-o`オプション(`--output`)を使用すると、コンソール上に連結したファイルを表示します。`pkgs.js`を読み込んだ場合、__このファイル順に依存を解決することに注意して下さい。__

1MB が 3MB に膨れているのは、ソースマップを含むためです。これにより

![スクリーンショット 2015-09-23 02.04.44.png](https://qiita-image-store.s3.amazonaws.com/0/28576/a9dce77e-da44-3b88-5bde-58b0f3372109.png)

ライブラリが投げた例外は、`pkgs.js`の行番号ではなく、そのライブラリの行番号へ移動できます。

> ソースマップ除去(`--no-sourcemap`)や、非可逆圧縮(`--mangle`)などのオプションがあります。`onefile --help`で確認してください。

## 所定のファイルを読み込みたい場合
Twitter社のBootstrapは、そのままでは使用できません。これは`bower.json`を修正することで使用できます。

まず、[前述の使用法](#使用法)と同じ手順で`bootstrap`をインストールします。

```bash:cmder
mkdir fuga
cd fuga

bower init # yes, yes, yes...
bower install bootstrap --save
# .
# ├── bower.json
# └── bower_components
#     ├── bootstrap
#     └── jquery
```

この後、書き込まれた`bower.json`は、下記のようになりますが、`onefile`で使用するのは`name`と`dependencies`のみです。説明のため、それ以外のプロパティを省略します。

```json:bower.json
{
  "name": "hoge",
  "dependencies": {
    "bootstrap": "~3.3.5"
  }
}
```

`onefile -o pkgs`コマンドが__失敗することを確認します__。

```bash:cmder
onefile -o pkgs
# Found:
#      247.6 kB bower_components/jquery/dist/jquery.js
#      68.89 kB bower_components/bootstrap/dist/js/bootstrap.js
# Yield:
#     861.79 kB pkgs.js
```

> bootstrap は css と js を併用するフレームワークなので、上記の結果は、意図したファイルが取得出来ていません。

そして、`overrides`を書き加えます。これは`onefile`の依存ライブラリである、[main-bower-filesのオプション](https://github.com/ck86/main-bower-files#options)です。

```json:bower.json
{
  "name": "hoge",
  "dependencies": {
    "bootstrap": "~3.3.5"
  },
  "overrides": {
    "bootstrap": {
      "main": [
        "dist/css/bootstrap-theme.css",
        "dist/css/bootstrap.css",
        "dist/js/bootstrap.js"
      ]
    }
  }
}
```

`onefile -o pkgs`コマンドが__成功することを確認します__。

```bash:cmder
onefile -o pkgs
# Found:
#      247.6 kB bower_components/jquery/dist/jquery.js
#       35.1 kB bower_components/bootstrap/dist/css/bootstrap-theme.css.js
#     616.01 kB bower_components/bootstrap/dist/css/bootstrap.css.js
#      68.89 kB bower_components/bootstrap/dist/js/bootstrap.js
# Yield:
#       2.38 MB pkgs.js
```

`pkgs.js`を`<script src="pkgs.js">`から読み込むと、上から順番にパッケージを読み込みます。

```html:index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width initial-scale=1">
    <script src="pkgs.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-default">
      <div class="container-fluid">
        <div class="navbar-header">
          <ul class="nav navbar-nav">
            <li><a href="#">This is Example</a></li>
          </ul>
        </div>
      </div>
    </nav>
  </body>
</html>
```

上記の`index.html`を開けば、下記のようにcssも含めて読み込まれたことが確認できます。

![スクリーンショット 2015-09-23 06.18.04.png](https://qiita-image-store.s3.amazonaws.com/0/28576/96471c6c-05b3-cdde-394d-d8de5aeee47a.png)

# 留意点
サポートしている拡張子は`.js`および`.css`のみです。それ以外は`overrides`に指定しても`onefile`が無視します。

## `.js`
`bower_components`から独立して動作するようになります。ただし、ソースマップでは`bower_components`内を引き続き参照することに注意してください。

## `.css`
__`.js`に変換します。__これは、ファイル数を増やさないための意図的な変換です。この処理により、`.css.js`が`pkgs.js`に追加され、実行時に`<style>`を`<head>`に挿入します。

また、css内に`url(http://foo/bar.gif)`や`url(./baz.jpg)`のような外部リソース参照がある場合は、__datauriに変換してcss自身に埋め込む__ことに注意して下さい。アイコンフォントは`slick-carousel`で動作を確認しています。

この、かなり実験的な機能は、将来廃止されるかもしれません。

報告・要望・PR
---
[該当リポジトリ](https://github.com/59naga/onefile/issues)まで、issue / PRをお願いします。