Bower入門(応用編)

Bower入門(応用編)

さて、応用編を書いていきます。
基礎編ではBowerのインストールとライブラリ管理する上での基本的なコマンドを紹介しました。
応用編ではBowerのライブラリを管理する上で利用するべきツールやライブラリを公開する上で心がけるべきことについて書いていきます。

少し長いのでサマリ

  • Bowerを管理する上で利用すると良いツール:grunt-bower-taskがオススメです
  • ライブラリを公開する上で心がけること、その1:mainとignoreをちゃんと書きましょう
  • ライブラリを公開する上で心がけること、その2:ちゃんとgit tagを使ってバージョン管理しましょう

Bowerからインストールしたライブラリを利用する場合

前回の基礎編で少し書きましたが、おさらいすると、Bowerはあくまでパッケージマネージャなので、インストールしてもフォルダ構造までは変えてくれません。

なのでフォルダの構造を意識して、

<script src="/components/jquery/jquery.js" ></script> // jqueryの直下にjquery.jsがある
<script src="/components/impress.js/js/impress.js"></script> // impress.jsの下にjsフォルダがあって、更にその下に目的のimpress.jsがある

みたいに記述しないといけません。

少し前に Uzulla さんもブログ にこんな内容を書いてました。

じゃあどうやって実際にDLしたファイルを使うのか

これはクーールなやり方は特になくて、普通にそのはいったファイルを

  <script src="/bower_components/jquery/index.js"></script>

しましょうって書いてある、えっ、オシャレじゃないよ!っておもったけど、
まあ統一的なものがないし、どうしようもないのかな。
(オシャレなやり方あるならだれか教えて下さい…)

オシャレなやり方かどうかは分かりませんが、RequireJSを使ったり、 Grunt を併用することで、ある程度フォルダ構造を意識しないで利用することが可能です。
僕はGruntが好きなのでgrunt-bower-taskというタスクを併用すれば、レイアウトマネージャーとしての機能が活用ができるのでお勧めです。

grunt-bower-taskを使う

grunt-bower-taskを使うと、レイアウトを変えることが可能です。

利用するにはまず、gruntを入れて、その後にgrunt-bower-taskをインストールしてください。

$ npm install -g grunt-cli
$ npm install grunt --save-dev
$ npm install grunt-bower-task --save-dev // grunt-bower-task のインストール

終わったら、Gruntfile.jsを以下のように書きましょう。

module.exports = function (grunt) {
  grunt.initConfig({
    bower: {
      install: {
        options: {
          targetDir: './lib', //ライブラリの配置先のディレクトリ
          layout: 'byType', // レイアウト、説明は後述します
          install: true, //grunt実行時にbower installを実行するかどうか
          verbose: false, // ログの詳細を出すかどうか
          cleanTargetDir: true, // targetDirを削除するかどうか
          cleanBowerDir: false // bowerのcomponentsディレクトリを削除するかどうか
        }
      }
    },
  });
  grunt.loadNpmTasks('grunt-bower-task');
};

実行する時は、

$ grunt bower:install

とすると、 bower.json の main プロパティに記されたファイルだけを targetDir以下に配置してくれます。

例えば jQueryの bower.json を読むと、mainプロパティに jquery.js と記述されているのがわかります。
grunt-bower-taskにより、jquery.jsがlib以下に配置されます。

lib
├── jquery
│   └── jquery.js

前回の基礎編で main ignore がライブラリ登録時に重要だと言った理由は grunt-bower-task等のbower拡張ツールがこれらの情報を利用して配置するからです。

ただし、mainが書かれていないライブラリはまだまだたくさんあります。 そうなると grunt-bower-task でも何を配置して良いか分からず、結果全てを配置することになってしまいます。


例えばunderscoreはmainが記述されていないので、入れるとこんな感じになります。。。

lib
├── jquery
│   └── jquery.js
└── underscore // 不要なファイルまで取得される
    ├── CNAME
    ├── CONTRIBUTING.md
    ├── LICENSE
    ├── README.md
    ├── Rakefile
    ├── bower.json
    ├── docs
    │   ├── docco.css
    │   ├── favicon.ico
    │   ├── images
    │   │   ├── background.png
    │   │   └── underscore.png
    │   └── underscore.html
...

なので、 bowerのライブラリを登録する際には、必ずmainとignoreを書くようにしましょう。

これはgrunt-bower-task以外のツールでも同じです。bower-installerやgrunt-bowerful等、色んなbower拡張ツールがありますが全てbowerのmainを読み込みます。

Bowerの仕様にもmainはbowerが直接利用するものではなく、ビルドツールから利用されるものである、と明記されています。

どんなツールが使われるか分かりませんが、作法として書くようにしたほうが良いと思います。

mainがないライブラリの扱い方

先程述べた通り、mainに何も記述されていないライブラリはデフォルトのままだとgithubに登録されているフォルダ構成でダウンロードされてしまいます。ただし、grunt-bower-taskでは、bower.jsonに記述を加える事で、これを解決できます。

■ bower.json

{
  "name": "My application",
  "version": "0.0.1",
  "main": index.js
  "ignore": [
    "**/.*",
    "node_modules",
    "components"
  ],
  "dependencies": {
    "jquery": "~2.0.0",
    "underscore": "~1.4.4"
  },
  "exportsOverride": { //ここが肝。exportsOverrideを加える事でタイプを定義し、レイアウトを変えられる。
    "underscore": { //キーがtypeとして扱われる、
      "js": "**/*.js" // css:"**/*.css"とかimg:"**/*.png"とかも併記できる。
    }
  }
}

exportsOverrideを記述した上で Gruntfile.jsの layout オプションに以下のように設定します。

■ Gruntfile.js

module.exports = function (grunt) {
  grunt.initConfig({
    bower: {
      install: {
        options: {
          targetDir: './lib', 
          layout: 'byType', // byTypeかbyComponentか任意のレイアウト関数を登録できます。
          install: true,
          verbose: false,
          cleanTargetDir: true,
          cleanBowerDir: false
        }
      }
    },
  });
  grunt.loadNpmTasks('grunt-bower-task');
};

この状態で

$ grunt bower:install

と実行すると、以下のようにmainが設定されていないライブラリでもjsだけをフォルダに集約することができます。

lib
├── jquery
│   └── jquery.js
└── js
    └── underscore
        ├── arrays.js
        ├── chaining.js
        ├── collections.js
        ├── functions.js
        ├── index.js
        ├── jquery.js
        ├── jslitmus.js
        ├── objects.js
        ├── qunit.js
        ├── runner.js
        ├── speed.js
        ├── underscore-min.js
        ├── underscore.js
        └── utility.js

byComponentにすると以下のようになります。

├── jquery
│   └── jquery.js
└── underscore
    └── js
        ├── arrays.js
        ├── chaining.js
        ├── collections.js
        ├── functions.js
        ├── index.js
        ├── jquery.js
        ├── jslitmus.js
        ├── objects.js
        ├── qunit.js
        ├── runner.js
        ├── speed.js
        ├── underscore-min.js
        ├── underscore.js
        └── utility.js

せっかくなのでjqueryにも同じ定義を加えましょう。

■bower.jsonを以下のように書き換えましょう。

{
  "name": "My application",
  "version": "0.0.1",
  "main": index.js
  "ignore": [
    "**/.*",
    "node_modules",
    "components"
  ],
  "dependencies": {
    "jquery": "~2.0.0",
    "underscore": "~1.4.4"
  },
  "exportsOverride": { //ここが肝。exportsOverrideを加える事でタイプを定義し、レイアウトを変えられる。
    "underscore": {
      "js": "**/*.js"
    },
    "jquery": { // jqueryの定義を追加、この定義がなければmainが読み込まれる
      "js": "**/*.js"
    }
  }
}

再度gruntを実行すると、以下の様なフォルダ構造になります。

lib
└── js
    ├── jquery
    │   ├── jquery-migrate.js
    │   ├── jquery-migrate.min.js
    │   ├── jquery.js
    │   └── jquery.min.js
    └── underscore
        ├── arrays.js
        ├── chaining.js
        ├── collections.js
        ├── functions.js
        ├── index.js
        ├── jquery.js
        ├── jslitmus.js
        ├── objects.js
        ├── qunit.js
        ├── runner.js
        ├── speed.js
        ├── underscore-min.js
        ├── underscore.js
        └── utility.js

指定する時はこうなりますね、

<script src="/lib/js/jquery/jquery.js" ></script> // lib/js/<ライブラリ名>/<ファイル名>と良い感じにまとめられる
<script src="/lib/js/underscore/underscore.js"></script>

良い感じにjsファイルがまとめられて階層がフラットになったのでフォルダ構造を意識する必要が減ったと思います。

覚えてほしいこと
  • bowerのライブラリを登録する場合は mainとignoreを記述してください
  • grunt-bower-taskを使えばmainを取得したり、レイアウトを変える事ができます。
  • grunt-bower-taskを併用すればフォルダ構造がフラットになるので構造を意識する必要が若干減ります。

ついでなのでUzullaさんのブログに書かれていたハマりどころ全部答えてみる。

どうでもいいけど

  "dependencies": {
    "jquery": "~2.0.0",
    "blockui": "git://github.com/malsup/blockui", ←ここの最後のカンマでエラーになる
  }

このIE的挙動がイラッ♪とします。

なんかJSONのパーサーが違うんですかね(node初心者)

わりと(.bowerrcとか)設定ファイルの文法まちがってると、エラーなく死ぬ事も多いので、辛いですね

JSONのパーサーについて

まず、JSONのパーサーはどれも同じだと思います。手元でChromeSafariでやった感じだとケツカンマがあるとSyntax Errorになります。

Javascriptオブジェクトはケツカンマを許すものもありますが、JSONは仕様としてケツカンマを許しません。

JavaScriptとJSONとECMAScript - gomoh
JSONのRFC

なので、この問題はbower.jsonという名前を付けてしまった時点で発生する問題ですね。
ちなみにnpmもpackage.jsonなので同じ問題が発生します。

dependenciesを編集するだけなら直接bower.jsonを編集するのではなく、以下のようにsaveオプションを使いましょう。

$ bower install xxxx --save
$ bower install xxxx --save-dev

ただbowerrcはJSONである必要があったのか疑問ですね。npmrcはJSONじゃないので(確か)。

文法間違いでエラーを吐かないこと

これは本当に致命的だと思ったので、Issue(+ PullReq)を投げたら自分の修正方法じゃないエレガントな方法で解決してくれたので、最新版ではエラーをちゃんと吐くようになりました。なので、いますぐ

$ npm install -g bower

で、最新にすれば直ります。

bowerはコミットが盛んなので、常に最新にするように心がけたほうが良いかもしれません。




最後にbower のライブラリ公開方法

bower register
$ bower register <ライブラリ名> <github URL(git://から始まるReadonlyのURLにしましょう。)>

例:

$ bower register tmlib.js git://github.com/phi1618/tmlib.js.git


で登録できます、くどいようですが、登録の際には必ずmainとignoreを付けるようにしましょう。

後、git tagでちゃんとバージョンを設定する必要があります。

その際はsemverと呼ばれるバージョン管理体系に沿ってtagを設定してください。

gitのtagとbower.jsonのバージョンの間でミスマッチがあると下記のようなwarningが出ます。

mismatch The version specified in the bower.json of package <package_name> matches the tag
mismatch You should report this problem to the package author

このwarningが出たら、大抵の場合はbower.jsonのバージョン番号が古い時だと思うのでライブラリ管理者に伝えて適切なgit tagを打ってもらうかbower.jsonを書き換えてpullreqしましょう。

bower で登録したライブラリを解除したい時

特にコマンドはありません、

Unregister package requests · Issue #120 · bower/bower · GitHub

上記のissueに登録すると解除してくれるようです。

まとめ

  • Bowerを使うとフロントエンドのライブラリを管理することができます。
  • Bower自体の機能はかなりミニマルなのでgrunt-bower-task等のBower拡張ツールと併用したほうが実際に使う上では良いでしょう。
  • Bowerは常に最新に。
  • 公開するならmainやignoreはちゃんと書きましょう。
  • 公開するならgit tagでバージョン管理しましょう。

と長くなりましたが、応用編終わりです。疑問があれば答えます!

Bower入門(基礎編)

Bower入門

これから Bower について書いてきます。Bowerの使い方から実際に使う上で考慮することまで含めて書きます。
長くなりそうなので単に使うだけの基礎編とモジュールを作る上で気をつけることをまとめた応用編に分けて書きます。

Bower とは

Twitter社が作ったフロントエンド用のパッケージマネージャです。 Java で言う MavenRuby で言う gem、 Perl で言う cpan のようなものです。
Node.jsには npm と呼ばれるパッケージマネージャがありますが、それに強く影響を受けています。

パッケージマネージャを利用することでライブラリを自分で管理する必要がなくなり、管理するファイルの数を減らすことができます。
また、パッケージマネージャを利用することでライブラリのバージョン管理をしやすくなります。

さらに自分のライブラリを Bower components と呼ばれるリポジトリに登録することで 公開することが可能です。

ただし、後で細かく説明しますが、 Bower はあくまでパッケージマネージャであって取得したライブラリを使いやすく加工したり、取得したライブラリから javascript だけうまくフィルタして配置変換をしたり、といった機能はありません。

大体使い方知ってるよ、という方は最後の"覚えてほしいこと"の部分だけでも読んでいただくといいかもしれません。

Bower インストール方法

Node.jsを入れて、 npm を取得する必要があります。
Node.jsを入れるにはいくつか方法があるんですが、インストーラから入れるか Homebrewから入れると良いかと思います。

$ brew install node.js
$ node -v


もしも Homebrew が入っていなかったり、Node.jsのバージョン管理を簡易に行いたい場合は nodebrew がオススメです。

$ curl -L git.io/nodebrew | perl - setup
$ export PATH=$HOME/.nodebrew/current/bin:$PATH >> .bashrc (or .zshrc)
$ source ~/.bashrc (or .zshrc)
$ nodebrew install v0.10
$ nodebrew use v0.10
$ node -v

node.jsが入ったら npm を使ってbowerをインストールします。

$ npm install bower -g

bowerを試しに動かしてみましょう。

$ bower -v

バージョン番号が返ってくればbowerのインストール成功です。

bower init

Bowerの初期化をします。

$ mkdir bower_test && cd bower_test
$ bower init

いくつか質問されるので、以下のように答えましょう。

name: [bower_test] My application // 自分のライブラリの名前
version: [0.0.0] 0.0.1 // 自分のライブラリのバージョン番号
main file: [] index.js // 自分のライブラリのエンドポイント
add commonly ignored files to ignore list? (y/n): [y] y // 公開時に不要と思われるファイルを不要リストに追加するかどうか

すると、bower.jsonが作成されます。
このbower.jsonは依存関係及び自分のライブラリの情報を記述するためのファイルです。この bower.json に記載されている定義を利用して bower はライブラリの管理を行います。中身を確認すると、上述した設定が記載されているのがわかると思います。

■bower.jsonの内容:

{
  "name": "My Application",
  "version": "0.0.1",
  "main": "index.js",
  "ignore": [
    "**/.*",
    "node_modules",
    "components"
  ]
}

応用編で詳しく説明しますが、ライブラリを公開するわけではなく、単純にbowerで自分のプロジェクトのライブラリを管理するだけであれば main と ignoreの記述は不要です。

ただし、 bower にライブラリを公開するのであればmain と ignoreの記述は重要です。応用編で詳しく説明します。

覚えてほしいこと
  • bower init で初期化する
  • bower.jsonが作成される
  • bower.jsonにはライブラリの名前、依存関係が記述される重要なファイル

bower install

Bower でライブラリをインストールするのに使います。

試しに jQuery を入れてみましょう。

$ bower install jquery

これを実行すると、 bower.json の存在する場所と同じ所に components フォルダが作成され、そこに最新のjQueryが配置されます。

├── bower.json
├── components
│   └── jquery
│       ├── README.md
│       ├── bower.json
│       ├── component.json
│       ├── composer.json
│       ├── jquery-migrate.js
│       ├── jquery-migrate.min.js
│       ├── jquery.js
│       ├── jquery.min.js
│       └── package.json

jqueryにも色々バージョンがあります、バージョンを指定する場合は、以下のように記述しましょう。

$ bower install jquery#1.9.1

バージョン番号は全て指定する必要はありません。メジャーバージョンだけ指定すれば、そのバージョンの最新を入れてくれます。

$ bower install jquery#1

Bower Componentsに登録されていない場合でも直接URLを指定すれば取得出来ます。

$ bower install http://code.jquery.com/jquery-1.10.1.js
bower install --save/--save-dev

ただし、これだとライブラリは入りますが、bower.jsonには依存関係が記述されません。記述するには --save オプションを使いましょう。

$ bower install jquery --save


すると、下記のように bower.json に依存関係が追加されます。

{
  "name": "My Application",
  "version": "0.0.1",
  "main": "index.js",
  "ignore": [
    "**/.*",
    "node_modules",
    "components"
  ],
  "dependencies": {
    "jquery": "~2.0.1"
  }
}

bower.json内に dependencies が記述されていれば、今後は指定しなくとも以下のコマンドだけでライブラリがインストールされます。

$ bower install

便利!!

もしも test 目的などで開発中にしか使わないモジュールの場合は --save-dev オプションを使いましょう。

$ bower install mocha --save-dev

この場合も依存関係は記述されますが、 devDependencies と呼ばれるカテゴリに記述されます。

{
  "name": "My Application",
  "version": "0.0.1",
  "main": "index.js",
  "ignore": [
    "**/.*",
    "node_modules",
    "components"
  ],
  "dependencies": {
    "jquery": "~2.0.1"
  },
  "devDependencies": {
    "mocha": "~1.9.0"
  }
}

この devDependencies というカテゴリに記述されたライブラリは --production のオプションを指定するとインストールされません。

$ bower install --production

こうすることで本番環境では不要なライブラリを除外することができます。

bower install の ちょっとした裏技

bower install は bower i でも同じ事ができます。

$ bower i jquery // bower install jquery と同じ。

他にもショートカットコマンドがあります。

$ bower i jquery -S // bower install jquery --save と同じ。
$ bower i jquery -D // bower install jquery --save-dev と同じ。
$ bower i -P // bower install --production と同じ。
覚えてほしいこと
  • bower install <ライブラリ名> でライブラリを取得する。
  • bower install --save を使うと bower.json に依存関係を記述してくれる
  • bower.jsonに依存関係が記述されていれば bower install とタイプするだけで依存関係をインストールしてくれる。

bowerrc

bowerにはbowerrcと呼ばれる設定ファイルがあります。

bowerrcを利用することでデフォルトの配置先を変更することや検索の時の位置を変えることができます。
bower.jsonと同じ場所に .bowerrc という名前でファイルを作成し、下記のように記述します。

{
  "directory": "bower_components", // bower ライブラリの配置先。デフォルトはcomponents
  "json": "bower.json", // jsonファイルのパス
  "searchpath": [  // bowerライブラリを検索するときの検索パス、プライベートリポジトリを立てている場合に記述する
    "https://bower.herokuapp.com"
  ]
}
覚えてほしいこと
  • .bowerrc ファイルで bower の設定ができる
  • directory キーに設定するとbower ライブラリの配置先を変えられる。

bower search/lookup

ライブラリを検索するには bower search を使います。

$ bower search jquery

似たコマンドとして bower lookup というのがありますが、ライブラリ名の完全一致で検索します。

$ bower lookup jquery

どちらかというとlookupは名前解決に近いイメージで、searchはライブラリの検索に利用します。

bower list

自分がインストールしたライブラリを確認する時です。 bower ls でも同じ事になります。

$ bower list
$ bower ls

bower uninstall

アンインストールする時ですね。ほぼ説明不要かと。一応 --save, --save-dev でbower.jsonに書かれている依存も削除します。

$ bower uninstall jquery
$ bower uninstall jquery --save
$ bower uninstall jquery --save-dev

bower info

ライブラリのバージョンや情報を確認する時に使用します。

$ bower info jquery

jquery

  Versions:
    - 2.0.1
    - 2.0.0
    - 1.10.0
    - 1.9.1
    - 1.9.0
    - 1.8.3
    - 1.8.2
    - 1.8.1
    - 1.8.0
    - 1.7.2
    - 1.7.1
    - 1.7.0
    - 1.6.4
    - 1.6.3
    - 1.6.2
    - 1.6.1
    - 1.6.0
    - 1.5.2
    - 1.5.1
    - 1.5.0
    - 1.4.4
    - 1.4.3
    - 1.4.2
    - 1.4.1
    - 1.4.0
    - 1.3.2
    - 1.3.1
    - 1.3.0
    - 1.2.6
    - 1.2.3

あまり使わないけど覚えておくと良いコマンド

以下のコマンドはあまり使わないですが、覚えておくとふとした時に役に立つかも。

bower update

ライブラリをもう一度インストールするには bower update を使います。

$ bower update

なんかの拍子に失敗してインストールされた時とかに使えるかも。

bowerでインストールしたライブラリを使用する時

最初に述べましたが、Bower はあくまでパッケージマネージャで、指定されたライブラリを git clone して持ってくるだけです。

試しにいくつかライブラリを入れてみましょう。

$ bower i jquery
$ bower i impress.js


この時のフォルダ構造は以下のようになってます。

├── impress.js
│   ├── css
│   │   └── impress-demo.css
│   ├── index.html
│   └── js
│       └── impress.js
└── jquery
    ├── README.md
    ├── bower.json
    ├── component.json
    ├── composer.json
    ├── jquery-migrate.js
    ├── jquery-migrate.min.js
    ├── jquery.js
    ├── jquery.min.js
    └── package.json

見ての通り、目的のjsファイルを使おうとしても構造が違います。そのため、このままでは利用するためには

    <script src="/components/jquery/jquery.js" />
    <script src="/components/impress.js/js/impress.js" />

みたいにフォルダ構造を意識して設定しなければならず、若干面倒です。

よくGitHubGoogle Groupで議論になるのですが、この指定されたライブラリを取ってくるだけじゃなくてフォルダからjavascriptだけ取得したり、CSSだけ取得するようなレイアウトマネージャーとしての機能を提供して欲しいという話がbowerに出ます。

ただし、まだこれらの議論はまとまっておらず、今のところは別なツールで回避せざるをえないのが現状です。

この辺りの回避策は次のエントリである、Bower入門の応用編に書きます。

ひとまず基本的なインストールの仕方から使い方までまとめました。

jsCafeでBowerとYeomanについて話してきた。

これも先週の話なんですが、jsCafeでBowerとYeomanについて話して来ました。

Bower and Yeoman

※埋め込みスライド、矢印キーで動きます。

今回のjsCafeは結構盛りだくさんで、Backboneの話、jQueryの話とhotchemiさんのNode.jsの話で大分お腹いっぱいの所で自分のBowerとYeomanの話でもう聴講者はかなりパンパンだったんじゃないかと。

これからBowerについてとYeomanについてもう少し書いていこうと思う。
両方共、良いところがありながらイケてない所もあるので、調べつつこのブログでシリーズ化していけるといいかと。