[Grunt & Yeoman] grunt-bower-task で Bower を扱いやすくレイアウトする

Bower入門 完結編です。

.bowerrc でインストールディレクトリを指定しましたが、コンポーネント毎に様々な構成で格納されています。
[markdown]
grunt-bower-task で扱いやすいファイルレイアウトにしましょう。

> * [Bower: JavaScript のパッケージマネージャについて調べる | deadwood](https://www.d-wood.com/blog/2013/11/01_4977.html)
> * [Bower: JavaScript も CSS もまとめて管理する | deadwood](https://www.d-wood.com/blog/2013/11/10_5009.html)

開始前に、.bowerrc を消しておきました。

“`prettyprinted
% rm .bowerrc
“`

## 標準の状態を確認する

バージョン指定していろいろインストールしてみます。

“`prettyprinted
% bower install jquery#1 –save-dev
% bower install normalize-css#1 –save-dev
% bower install html5shiv#3 –save-dev
% bower install respond#1 –save-dev
“`

下記のような状態で配置されました。

“`prettyprinted
/bower_components
├── html5shiv
│   ├── dist
│   │   ├── html5shiv-printshiv.js
│   │   └── html5shiv.js
│   └── readme.md
├── jquery
│   ├── README.md
│   ├── bower.json
│   ├── component.json
│   ├── composer.json
│   ├── jquery-migrate.js
│   ├── jquery-migrate.min.js
│   ├── jquery.js
│   ├── jquery.min.js
│   ├── jquery.min.map
│   └── package.json
├── normalize-css
│   ├── LICENSE.md
│   ├── README.md
│   ├── bower.json
│   └── normalize.css
└── respond
├── README.md
├── cross-domain
│   ├── example.html
│   ├── respond-proxy.html
│   ├── respond.proxy.gif
│   └── respond.proxy.js
├── respond.min.js
├── respond.src.js
└── test
├── test.css
├── test.html
├── test2.css
└── unit
├── index.html
├── qunit
│   ├── qunit.css
│   └── qunit.js
├── test.css
├── test2.css
├── test3.css
└── tests.js
“`

/src/vendor 以下に必要なファイルだけあるとうれしいですよね。

“`prettyprinted
.
├── Gruntfile.coffee
├── README.md
├── bower.json
├── bower_components
│   ├── html5shiv
│   ├── jquery
│   ├── normalize-css
│   └── respond
├── dest
│   └── vendor
├── node_modules
├── package.json
└── src
└── vendor
“`

## インストール

grunt-bower-task をインストールします。

> * [yatskevich/grunt-bower-task](https://github.com/yatskevich/grunt-bower-task)

“`prettyprinted
% npm install grunt-bower-task –save-dev
:
:
grunt-bower-task@0.3.4 node_modules/grunt-bower-task
├── async@0.1.22
├── colors@0.6.2
├── wrench@1.4.4
├── lodash@0.10.0
├── rimraf@2.0.3 (graceful-fs@1.1.14)
└── bower@1.2.7 (junk@0.2.1, stringify-object@0.1.7, abbrev@1.0.4, which@1.0.5, chmodr@0.1.0, osenv@0.0.3, graceful-fs@2.0.1, archy@0.0.2, rimraf@2.2.2, bower-logger@0.2.1, open@0.0.4, bower-endpoint-parser@0.2.1, lru-cache@2.3.1, nopt@2.1.2, retry@0.6.0, tmp@0.0.21, mkdirp@0.3.5, q@0.9.7, semver@2.1.0, chalk@0.2.1, bower-json@0.4.0, request-progress@0.3.1, sudo-block@0.2.1, fstream@0.1.24, promptly@0.2.0, fstream-ignore@0.0.7, tar@0.1.18, glob@3.2.7, unzip@0.1.9, cardinal@0.4.2, request@2.27.0, handlebars@1.0.12, inquirer@0.3.5, mout@0.7.1, bower-config@0.5.0, update-notifier@0.1.7, bower-registry-client@0.1.5)
“`

## Gruntfile

Gruntfile.coffee に設定を書きます。

> * [Bower入門(応用編) – from scratch](http://yosuke-furukawa.hatenablog.com/entry/2013/06/04/085537)

“`
‘use strict’
module.exports = (grunt) ->
# プラグインの読み込み
grunt.loadNpmTasks ‘grunt-bower-task’
# グラントタスクの設定
grunt.initConfig
# config
dir:
src: ‘src’
dest: ‘dist’
pkg: grunt.file.readJSON “package.json”
# Bower
bower:
install:
options:
targetDir: ‘<%= dir.src %>/vendor’
layout: ‘byComponent’
install: true
verbose: false
cleanTargetDir: true
cleanBowerDir: false
# タスクコマンドの設定
grunt.registerTask ‘default’, [‘bower:install’]
“`

### targetDir

配置するディレクトリを指定します。

### layout

後述します。

* byType
* byComponent

### install

grunt 実行時に、bower install をするかコントロールする。
下記ログを参照のこと。

### verbose

詳細なログを表示するか。

true

“`prettyprinted
% grunt bower:install
Running “bower:install” (bower) task
>> Cleaned target dir /Users/****/projects/gruntSample/src/vendor
>> Installed bower packages
grunt-bower copying bower_components/html5shiv/dist/html5shiv.js -> src/vendor/html5shiv/html5shiv.js
grunt-bower copying bower_components/html5shiv/dist/html5shiv-printshiv.js -> src/vendor/html5shiv/html5shiv-printshiv.js
grunt-bower copying bower_components/normalize-css/normalize.css -> src/vendor/normalize-css/normalize.css
grunt-bower copying bower_components/jquery/jquery.min.js -> src/vendor/jquery/js/jquery.min.js
grunt-bower copying bower_components/respond/respond.min.js -> src/vendor/respond/respond.min.js
>> Copied packages to /Users/****/projects/gruntSample/src/vendor
Done, without errors.
“`

false

“`prettyprinted
% grunt bower:install
Running “bower:install” (bower) task
>> Cleaned target dir /Users/****/projects/gruntSample/src/vendor
>> Installed bower packages
>> Copied packages to /Users/****/projects/gruntSample/src/vendor
Done, without errors.
“`

### cleanTargetDir

上記ログの Cleaned target dir がそれにあたる。
実行時に ターゲットディレクトリ内を削除するかどうか。
今回の場合は、/src/vendor 配下がその対象になる。

### cleanBowerDir

実行時に Bower のコンポーネントを削除するかどうか。
今回の場合は、/bower_components 配下がその対象になる。

## grunt bower でレイアウトを実行する

では実行してみます。

“`prettyprinted
% grunt bower:install
Running “bower:install” (bower) task
>> Cleaned target dir /Users/****/projects/gruntSample/src/vendor
>> Installed bower packages
>> Copied packages to /Users/****/projects/gruntSample/src/vendor
Done, without errors.
“`

respond を除き、自動でレイアウトされました。

“`prettyprinted
src
├── sample.html
└── vendor
├── html5shiv
│   ├── html5shiv-printshiv.js
│   └── html5shiv.js
├── jquery
│   └── jquery.js
├── normalize-css
│   └── normalize.css
└── respond
├── README.md
├── cross-domain
│   ├── example.html
│   ├── respond-proxy.html
│   ├── respond.proxy.gif
│   └── respond.proxy.js
├── respond.min.js
├── respond.src.js
└── test
├── test.css
├── test.html
├── test2.css
└── unit
├── index.html
├── qunit
│   ├── qunit.css
│   └── qunit.js
├── test.css
├── test2.css
├── test3.css
└── tests.js
“`

Bower の仕様に未対応のコンポーネントは、githubに登録されているフォルダ構成のままとなってしまうようです。

## 未対応のコンポーネントをレイアウトする

未対応のコンポーネントをレイアウトするために、プロジェクトの bower.json に exportsOverride 指定を書き加えます。
あわせて jquery も指定し、動作を確認します。
Type に javascript を、対象にすべての .js ファイルを指定します。

bower.json

“`javascript:bower.json
“devDependencies”: {
“jquery”: “1”,
“normalize-css”: “1”,
“html5shiv”: “3”,
“respond”: “1”
},
“exportsOverride”: {
“respond”: {
“”: “respond.min.js”
},
“jquery”: {
“javascript”: “**/*.js”
}
}
}
“`

`grunt bower:install` を再度実行すると、ファイルがキレイに配置されました。

“`prettyprinted
src
├── sample.html
└── vendor
├── html5shiv
│   ├── html5shiv-printshiv.js
│   └── html5shiv.js
├── jquery
│   └── javascript
│   ├── jquery-migrate.js
│   ├── jquery-migrate.min.js
│   ├── jquery.js
│   └── jquery.min.js
├── normalize-css
│   └── normalize.css
└── respond
└── respond.min.js
“`

### byComponent

上記の jquery を見てみると、コンポーネント名、タイプ名の順で格納されています。
これは Gruntfile 内の `layout: ‘byComponent’` の設定です。

### byType

`layout: ‘byType’` ではこのように配置されます。

“`prettyprinted
src
├── sample.html
└── vendor
├── html5shiv
│   ├── html5shiv-printshiv.js
│   └── html5shiv.js
├── javascript
│   └── jquery
│   ├── jquery-migrate.js
│   ├── jquery-migrate.min.js
│   ├── jquery.js
│   └── jquery.min.js
├── normalize-css
│   └── normalize.css
└── respond
└── respond.min.js
“`

うまく配置できそうです。

> * [GruntとBowerを使ってWeb開発用のテンプレートを作成する – タチコマ好きなエンジニアのブログ](http://yukihir0.hatenablog.jp/entry/2013/08/06/224722)
>
> ここまでで作成したpackage.json、bower.json、Gruntfile.jsをリポジトリに格納しておけば、npm installとgruntコマンドの実行で指定したバージョンの必要なパッケージがしかるべきディレクトリにダウンロードされる。すばらしい!!

“`prettyprinted
% npm install
% grunt
“`
[/markdown]