tkiryu’s blog

本ブログの内容は個人の意見です。所属組織の公式見解ではありませんのであしからず。

ASP.NET MVC プロジェクトで npm と Nuget を使い分ける

-- この記事は2016/10/28(Fri)現在の情報に基づいています --

この記事をざっくり言うと

前回の記事の補足的内容で、

tkiryu.hatenablog.com

ASP.NET MVC プロジェクトに npm 入れたのはいいけど、もともと Nuget もあるしどう使い分けよう、と悩んだときに

  • npm ではフロントエンドのパッケージだけ管理
  • Nuget ではバックエンドのパッケージだけ管理

すればいいんじゃないか、という話です。

npm と Nuget を共存させた場合の問題

デフォルトのMVC プロジェクトテンプレートでは、Nuget で jQuery や Bootstrap などのフロントエンドパッケージが管理されています。

Nuget だけでやりくりする場合は何の問題もありませんが、Nuget に加えて npm も使う場合、両方のパッケージマネージャーでフロントエンドパッケージが扱えてしまうので管理が煩雑になってしまいます。

npm と Nuget で役割分担する

そこで

  • npm = フロントエンド専用パッケージマネージャー
  • Nuget = バックエンド専用パッケージマネージャー

として使うのがいいんじゃないかなと思いました。

npm は今やWebフロントエンド開発には無くてはならないパッケージマネージャーで、恐らくここで見つからないものはまずないと思うので、フロントエンドのパッケージ管理は全て npm でやって、Nuget はバックエンドだけにすれば、管理がシンプルになって良さそうと感じたわけです。

ASP.NET MVC 5 プロジェクトテンプレートをカスタマイズ

上記のアイディアを実現すべく、デフォルトのASP.NET MVC プロジェクトテンプレートを使って、Nuget で管理されているフロントエンドパッケージを全て npm に移行してみたいと思います。

1. 用意した環境

2. Nuget からフロントエンドパッケージを全て削除

Nuget では以下のフロントエンドパッケージが管理されていたので、削除します。

3. npm で Nuget と同じフロントエンドパッケージをインストール

npm でのパッケージ名は以下のようになります。

  • bootstrap
  • jquery
  • jquery-validation
  • jquery-validation-unobtrusive
  • modernizr
  • respond.js ※IE8サポート終了した今となってはさすがに不要なのでインストールしませんでした。

4. npm での Modernizr のビルド設定

Modernizer の場合、npm でインストールしただけでは使えずビルドが必要になる点が、Nuget と異なります。

従来のバージョン 2.x までは modernizr.js という単一ファイルに、ブラウザ機能の検知ロジック全てが含まれていました。

しかしバージョン 3 からは、必要な検出機能のみをピックアップしてビルドしましょう、その方がファイルサイズが小さくなって読み込み時間が短縮されてWebページが高速化するからいいよね、ということになったためです。

Modernizr Modernizr Download Builder

現在の Modernizr のサイトでは、必要な検出機能を選択して

  • ビルドされた js ファイルそのものをダウンロード
  • ビルド用の config ファイルをダウンロード

などが行えるようになっています。

今回は後者の config ファイルを使って npm でビルドを行います。 前者のほうがすぐに使えて簡単ですが、config ファイルさえあればいつでも同じ構成で Modernizr をビルドしなおせるので後者のアプローチのほうが良いと思います。

実際に config ファイルをダウンロードして、プロジェクト直下に配置します。(機能は適当に選びました)

f:id:tkiryu:20161027230809p:plain

f:id:tkiryu:20161027231003p:plain

続いて、npm-scripts に Modernizer 用のビルドコマンドを記述します。

{
  "name": "myproject",
  "version": "1.0.0",
  "dependencies": {
    "bootstrap": "^3.3.7",
    "jquery": "^3.1.1",
    "jquery-validation": "^1.15.1",
    "jquery-validation-unobtrusive": "^3.2.6",
    "modernizr": "^3.3.1"
  },
  "scripts": {
    "build:modernizr": "modernizr -c modernizr-config.json -d Scripts/ -u",
    "postinstall": "npm run build:modernizr"
  }
}

「build:modernizr」という名前で記述しましたが、好きな名前をつけられます。

Modernizer コマンドのオプションは以下の3つで、

  • -c: config ファイルのパスを指定します。
  • -d: 出力先フォルダへのパスを指定します。
  • -u: 指定した場合、難読化/縮小化を行います。

プロジェクト直下に配置した modernizr-config.json ファイルを読んでビルドし、難読化/縮小化した上で、Scripts フォルダに出力されるようにしています。

また、「postinstall」を使って、npm install が終わったあとに「build:modernizr」が自動実行されるようにしておきます。

※npm-scripts の詳細については、以下の記事がとても良くまとまっています。

ics.media

さて、上手く動作するか確認してみます。

一旦 node_modules 配下を全て削除してから、package.json を右クリック > パッケージの復元 を実行します。

node_modules フォルダにフロントエンドパッケージが全てインストールされ、かつ、Scripts フォルダに Modernizr.js が生成されていれば成功です。

5. BundleConfig.js のパスを書き換え

最後に BundleConfig.js 内の js, css の参照パスを書き換えます。

using System.Web;
using System.Web.Optimization;

namespace FrontendWebDev
{
    public class BundleConfig
    {
        // バンドルの詳細については、http://go.microsoft.com/fwlink/?LinkId=301862  を参照してください
        public static void RegisterBundles(BundleCollection bundles)
        {
            BundleTable.EnableOptimizations = true;
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/node_modules/jquery/dist/jquery.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/node_modules/jquery-validation/dist/jquery.validate.js",
                        "~/node_modules/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"));

            // 開発と学習には、Modernizr の開発バージョンを使用します。次に、実稼働の準備が
            // できたら、http://modernizr.com にあるビルド ツールを使用して、必要なテストのみを選択します。
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr.js"));

            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                      "~/node_modules/bootstrap/dist/js/bootstrap.js"));

            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/node_modules/bootstrap/dist/css/bootstrap.css",
                      "~/Content/site.css"));
        }
    }
}

6.実行確認

プロジェクトを実行して問題なく Web ページが表示されるか確認してみます。

f:id:tkiryu:20161028014404p:plain

成功です!

Modernizer のビルド設定は少し面倒でしたが、もともと Nuget で管理されていたフロントエンドパッケージは全て npm へ移行することができました。

作成したプロジェクトはテンプレートとしてGitHub にアップしましたのでご自由にお試しください。

github.com