Visual Studio 2013 で Bower を使う【利用編】
クロスワープの大鷲です。
前回は、Bower を使うために必要なツールをセットアップしたところで終わってしまいました。
今回は、実際に Bower を利用してみます。
プロジェクトを作る
Visual Studio 2013 を立ち上げて、Web アプリケーション プロジェクトを作りましょう。
ソリューション エクスプローラーから「NuGet パッケージの復元の有効化」をしておきます。
続いて、コマンド プロンプトでプロジェクトのあるディレクトリを開き、以下のように入力します。
bower init
いくつか質問されますが、回答内容はさほど重要ではありません。すべて既定値で Enter キーを押していくだけでも構いません。
一通り終わると、ディレクトリに bower.json というファイルが作られます。
このファイルは重要なのでソース管理に追加しておきましょう。
jQuery のインストール
Web アプリケーション プロジェクトを作成すると、既に NuGet 経由で jQuery がインストールされていますが、それは一旦置いておいて、Bower 経由で jQuery を入れてみます。
コマンド プロンプトで
bower install jquery --save
と実行してください。最後の --save を忘れないように。
完了すると、プロジェクト ディレクトリ内に bower_components というディレクトリができます。中には jQuery が入っているはずです。
また、bower.json に dependencies セクションが作られ、jQuery が登録されています。
{ "name": "VSBower", "version": "1.0.0", "authors": [ "owashi <owashi@crosswarp.com>" ], "license": "MS-PL", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "jquery": "~2.1.3" }, "private": true }
bower install の時につけた --save オプションは、この dependencies に登録するという意味です。
再インストールしてみる
このプロジェクトは jQuery を使うという情報が bower.json に記録されましたので、今後はいちいち bower install する必要はありません。
試しに bower_components ディレクトリを削除した上で、
bower install
と叩いてみましょう。
Bower は bower.json を読み取って、自動的に jQuery を再インストールしてくれます。
NuGet で言う「NuGet パッケージの復元の有効化」と同じことです。
このため、bower.json がソースコード管理にコミットされていれば、bower_components ディレクトリをコミットする必要はありません。
リポジトリからコードを取得したら、まず
bower install
すればいいわけです(ビルド サーバーでの自動ビルドの際は、まずこのコマンドを実行するように設定しておきます)。
繰り返しますが、最初のインストールの時に --save を付けていないとこうはいきませんので、忘れないように注意してください(実際、よく忘れるんです)。
Bootstrap もインストールしてみる
bower install bootstrap --save
と叩けばインストール完了です。
なお、他にどんなパッケージがあるのかは、Bower の公式サイトで検索できます。
Bower 版の jQuery と Bootstrap を使う
インストールができたら、VS のプロジェクトに追加しましょう。
まずは NuGet 版と同じようなファイルを追加しておきます。こんな感じでしょうか。
画像には写っていませんが、bower.json も追加しておいてください。
続いて、App_Start フォルダーの下にある BundleConfig.cs も、bower_components を参照するように書き換えましょう。
namespace VSBower { using System; using System.Web; using System.Web.Optimization; public class BundleConfig { // バンドルの詳細については、http://go.microsoft.com/fwlink/?LinkId=301862 を参照してください public static void RegisterBundles(BundleCollection bundles) { /* bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")); */ bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/bower_components/jquery/dist/jquery.js")); bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate*")); // 開発と学習には、Modernizr の開発バージョンを使用します。次に、実稼働の準備が // できたら、http://modernizr.com にあるビルド ツールを使用して、必要なテストのみを選択します。 bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/Scripts/modernizr-*")); /* bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/Scripts/bootstrap.js", "~/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css")); */ bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/bower_components/bootstrap/dist/js/bootstrap.js", "~/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/bower_components/bootstrap/dist/css/bootstrap.min.css", "~/Content/site.css")); } } }
普通は古いコードをコメントで残したりはしませんが、ここではわかりやすく新旧比較するために敢えてこうしています。
ここまでできたら、NuGet から Bootstrap はアンインストールしてしまって構いません(jQuery はまだ消せません)。
その他のライブラリも Bower に移行してみる
Web アプリケーション プロジェクトを作ると、最初から NuGet でインストールされているフロントエンド ライブラリには、以下のようなものがあります。
- Bootstrap
- jQuery
- jQuery Validation
- jQuery Unobtrusive Validation
- Modernizr
- Respond JS
Modernizr 以外は Bower でも公開されていますので、Bower に移行することができます。
まとめてやってしまいましょう(jQuery Validation は jQuery Unobtrusive Validation の依存性として自動的にインストールされます)。
bower install jquery-validation-unobtrusive respond-minmax --save
注目すべきは、jQuery Unobtrusive Validation は Microsoft 製のパッケージであり、それが Bower に登録されているということです。
ここからも、Microsoft が Bower にコミットしていく姿勢が見られます。
さて、追加したファイルをプロジェクトに含めて、BundleConfig.cs も書き換えましょう。
namespace VSBower { using System; using System.Web; using System.Web.Optimization; public class BundleConfig { // バンドルの詳細については、http://go.microsoft.com/fwlink/?LinkId=301862 を参照してください public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/bower_components/jquery/dist/jquery.js")); /* bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate*")); */ bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/bower_components/jquery-validation/dist/jquery.validate.js", "~/bower_components/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js")); // 開発と学習には、Modernizr の開発バージョンを使用します。次に、実稼働の準備が // できたら、http://modernizr.com にあるビルド ツールを使用して、必要なテストのみを選択します。 bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/Scripts/modernizr-*")); /* bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/bower_components/bootstrap/dist/js/bootstrap.js", "~/Scripts/respond.js")); */ bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/bower_components/bootstrap/dist/js/bootstrap.js", "~/bower_components/respond-minmax/dest/respond.min.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/bower_components/bootstrap/dist/css/bootstrap.css", "~/Content/site.css")); } } }
ここまで終わったら、NuGet からは削除してしまいましょう。
Modernizr は消さないように気を付けてくださいね。
jQuery の分裂
最近のちょっとした事件として、jQuery Plugin Registry が npm に移行したという件が挙げられます。
前回、npm のことを
サーバーサイド用なのでどちらかと言えばバックエンド パッケージ マネージャーです(でした)。
と書いたのは、この件が、npm がフロントエンド ライブラリに進出しようとしているように見えたからです。
しかし、jQuery 自体は Bower でインストールすることを推奨しているようです。
今後どうなるのでしょうか。
それはともかく、今回は Bower を使って進めていきます。
実はバグっているコード
NuGet から Bower に移行するに伴って書き換えた BundleConfig.cs ですが、実はわかりづらいバグが潜んでいます。
デバッグモードで実行すると動いてしまうのですが、リリースモードで、Web.config を
<system.web> <compilation debug="false" targetFramework="4.5"/> </system.web>
のようにしたり、あるいは、デバッグモードでも JavaScript や CSS の最適化を有効にするために、
BundleTable.EnableOptimizations = true;
などという設定を入れると、Bootstrap の Glyphicon や jQuery UI を使っている場合に、画像が出なくなります。
これは、Bundle に伴って CSS の URL が
~/bower_components/bootstrap/dist/css/bootstrap.css
から
~/bundles/bootstrap
に変わっても、Glyphicon の画像(フォント)ファイルは CSS ファイルからの相対パスで読み込もうとするので、
~/fonts/glyphicons-halflings-regular.eot
という実在しないパスを読み込もうとして失敗するためです。
最適化を有効にしなければ CSS の URL が変わらないため発生せず、また、発生したとしても動作に致命的な影響を及ぼさない小さな画像のため、非常にわかりづらい問題です。
この問題を回避するためには、Bundle のパスを変更するとか、CssRewriteUrlTransform クラスを使うといった方法がありますが、今回は思い切って Bundle を使うのをやめて gulp を使って対応したいと思います。
というところで、gulp については次回。
最後までお読み頂き、ありがとうございました。