tkiryu’s blog

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

.NET Conf 2017 Tokyo で登壇してきました

– この記事は 2017/10/13(Fri) 現在の情報に基づいています –

先日開催された .NET Conf 2017 Tokyo で登壇してきましたので、その振り返りをしたいと思います。

発表内容

発表スライドはこちらです。

発表内容としては大きく2つ

  1. ASP.NET Core 2.0 で追加された Angular SPA テンプレートの紹介
  2. ASP.NET Core のプロジェクトと、Angular CLI で作成したプロジェクトを統合する方法

でした。

発表内容補足

Angular 用 の SPA テンプレートは

  • Client Side Routing
  • Server Side Prerendering
  • webpack dev middleware
  • Hot module replacement

の機能を備えたテンプレートです。これはこれで良いのですが、Angular やるなら Angular CLI 使わなきゃ損、というのが今回の主張だったのですが、発表のあとで「結局、テンプレートの方が高機能ってことですよね」と言われてしまったので、この場を借りて補足しておきたいと思います。

  • Client Side Routing

に関しては、Angular CLI では ng new 時に --routing オプションをつけてあげると、ルーティングモジュールを含んだ形でプロジェクトを生成してくれます。

ng new my-app --routing

ルーティングモジュールの中身は 公式ページのガイド に沿って実装すればよいだけなので、Angular SPA テンプレートじゃないとダメというわけではありません。

  • webpack dev middleware

に関しては、Angular CLI でもデフォルトで同等の機能(編集保存するたびに自動コンパイル)があります。

  • Hot module replacement

に関しては、Angular CLI でも HMR の手順 どおりに設定することで有効にすることができます。

唯一 Angular CLIASP.NET Core の組み合わせで Server Side Prerendering を実現することはできない(と今のところ思っていますが、やりようがないか調べ中)ですが、それ以外は、Angular CLI でも簡単に構成することができますし、Angular CLI を使うことでそれ以上の恩恵を受けることができると思います。

特に大きいのが Angular パッケージのアップデートです。ASP.NET Core に内包された状態だと、パッケージのアップデートは手動で行わなければなりません。また、独自のビルドロジックになっているので、Angular のアップデートに伴ってビルド方法も変更しなくてはならなくなることも想定されます。Angular CLI の場合は、パッケージ管理も、ビルド方法も、Angular CLI さえアップデートすれば完了します。このメンテナンス性の高さは非常にアドバンテージがあると思います。

以上の理由から Angular CLI の使用を推すわけです。

なお、ASP.NET Core で Angular CLI を使いたいという要望は多く、Github 上に Issue:Add new Angular CLI-based template も登録されているので、今後の進展が楽しみです。

所感

  • 時間配分を間違え、しかも、時間オーバー
  • 時間が無くなるにしたがって次第に早口に、噛みまくり
  • 一番話したかった部分を十分に伝えられなかった

などいろいろ反省点が多く、力量不足を感じました。セッションに足を運んでいただいた方々には、理解しにくい点、聞き取りづらい点など多々あったかと思うと、申し訳ない気持ちです。

もしまた機会を頂けたら、今回の反省点を活かして再チャレンジできたらなと思います。

最後に

運営の皆さま、このような大きなコミュニティイベントで貴重な登壇機会をいただきまして本当にありがとうございました。非常によい経験をさせていただきました。またぜひ参加できればと思います。

10/19 追記:使用したデモ

github.com

Angular is a Platform

– この記事は2017/06/23(Fri)現在の情報に基づいています –

ng-japan 2017 に参加してきました。今年の ng-japan は Keynote があって、Angular Core Team の Stephen Fluin 氏からお話が聞けた貴重な機会でした。その Keynote の中であった話で、特別スゴイことだったとか目新しいことだったとか、そういうことではなかったんですが個人的にとても納得のいった話があったので、それについて書きます。

ng-japan 2017 公式資料

What is Angular

Keynote: Stephen Fluin (Angular Core Team) docs.google.com

f:id:tkiryu:20170620225747p:plain

の問いに対する答えとして Angular is a platform … という話がありました。単なる Library にあらず、Framework でもなく、Platform であると。これを聞いて、おぉーなるほど!!と激しく納得した、そういう話です。今回のブログで言いたかったことはこれだけです。前置き長くてすみません。

どうしてそんなに激しく納得したのかというと、

  • .NET Framework を使ってデスクトップアプリを作るように
  • Android/iOS SDK を使ってモバイルアプリを作るように
  • Angular を使って Web アプリを作る

ということで、つまり今や Angular は .NET Framework や なんちゃらSDK に匹敵するレベルのものなんだと思った瞬間、自分の中で妙にスッキリしたからです。

そもそも Platform ってなに?という話でいくと、「ソフトウェア開発のための基本環境を提供しているもの」といった定義がググると出てきて、多分

  • ビルド環境
  • 実行環境
  • テスト環境

あたりの環境が揃っていることが条件で、確かに今の Angular にはそれらが全て揃っているなと感じます。

ただ個人的には、Angular が Platform だと言えるのは Angular CLI のおかげで、これなしでは Framework の域を超えられなかったのではないかと思います。それくらい Angular CLI の存在は大きいと思っています。

Angular CLI のおかげで、コマンド一発でプロジェクトを生成することができて、ビルド環境、実行環境、テスト環境まで提供してくれます。もうスクラッチで環境構築する必要はなくなりました。Grunt、Gulp、browserify、webpack 等を使ってスクラッチで環境を作っていた頃が遠い昔のことのように思えます。

デスクトップアプリを作るときに、Visual Studio を使ってプロジェクトを作りこそすれ、決してソリューションファイルをスクラッチでは書かないと思います。Angular を使って Web アプリを作るということは、そういうことなんだと思います。

まとめ

  • Angular は Platform なり。
  • Angular が Platform なのは Angular CLI のおかげ。(個人的見解)
  • もうスクラッチで環境を作るのはやめて、Angular CLI を使おう。※Angular で Web アプリを作るとき限定

ASP.NET Core のドキュメント日本語化はじめました

– この記事は2017/03/24(Fri)現在の情報に基づいています –

ASP.NET Core のドキュメント、日本語化されていないなー、ということで、自分で日本語化することにしました。 とはいえ、さすがに全部というわけにはいかないので、以下の Fundamentals の部分に限定して現在翻訳中です。

docs.microsoft.com

ASP.NET Core 自体の学習になることはもちろん、英語の学習にもなり、さらには、自分が日本語化したドキュメントが他の方の役にも立つとなると、一石三鳥でこんなに良いことはありません。

オリジナルのドキュメントは Github で管理されているので、リポジトリをフォークして日本語化していくでも良かったのですが、編集完了時に毎回コミットしないといけないのが面倒だったので、Qiita で作業を進めることにしました。

qiita.com

現在までのところ、3セクション分の日本語化が終わっています。だいたいは直訳ですが、意味が伝わりにくい訳になってしまう文章もあるので、かなり表現を変えてしまっているものもあります。そういう意味で「意訳」としています。

今のところ2日で1セクションくらいのペースで進められているので、あと20セクション×2日=40日後には終わる感じですね、休まなければ(笑)

日本語化が終わった暁には、「ASP.NET Core のドキュメント日本語化おわりました」のタイトルでご報告しますので、お楽しみに。

Qiita の方では逐次アップデートしていくので、興味のある方はそちらをウォッチしてみてください。

それでは。

ASP.NET Core を始める際に知っておきたい Web フロントエンドツールの種類と最新トレンド

– この記事は2017/02/15(Wed)現在の情報に基づいています –

Web フロントエンドツールの種類

Web フロントエンドは流行り廃りが速く、ライブラリはもちろんのこと、ビルドツールも様々なものが次々に生まれキャッチアップしきれない、とよく言われます。しかし実は、そのツールが何を解決するためのものなのかというポイントを押さえておけばそれほど焦る必要はないと思っています。なぜなら、実はそれらツールが解決したい課題自体にほとんど変化がないからです。

Web フロントエンドのツールが解決したい課題は主に3つ

  1. ライブラリの管理
  2. ファイルのコンパイルやサーバー起動などのタスクを実行
  3. JavaScriptモジュールの依存関係をまとめる

です。

1.ライブラリの管理 ⇒ パッケージマネージャー

言わずと知れたパッケージマネージャーです。ライブラリの管理が役目ですが JavaScript のと言えばこの2つです。

  • npm
  • Bower
    (番外編)
    • JSPM
    • Yarn ※ 最近話題になっている npm と互換性のあるパッケージマネージャー

npm はもともと Node.js 上で動作するライブラリを管理するためのもの、Bower はブラウザ上で動作するライブラリを管理するためのものです。

少し前までブラウザのライブラリ管理には Bower が主な選択肢でしたが、モジュールバンドラー(後述します)の登場によって、Node.js スタイルのライブラリでもブラウザで実行可能な形式に変換して使用できるようになったため、npm さえあれば Bower が無くても困らない状況が生まれました。 他にも

  • ES2015(ES6) の import 構文による JavaScript のモジュール機構を使ったコーディングスタイルが主流となりつつあること。
  • Angular(旧称 Angular 2) などの最新フレームワークのパッケージが Bower ではホストされていないこと。
  • npm の登録パッケージ数が圧倒的。

などの要因もあり、現在では Bower よりも npm が好まれれる傾向があります。

ちなみに、npm と Bower のパッケージ数を比較したチャートを掲載しておきます。いかに npm が数で圧倒しているか分かります。おそらく npm にあって Bower にないパッケージはほとんどないと思います。

http://www.modulecounts.com/ f:id:tkiryu:20170214032633p:plain

2.タスクの実行 ⇒ タスクランナー

Web フロントエンドで実施すべきタスクは多岐にわたります。JSファイルやCSSファイルの minify、 concat、画像の最適化、TypeScript や Babel のトランスパイル、開発用サーバーの起動、などです。これらのタスクを手動で実行するのはとても手間がかかります。そこで、タスクを自動実行してくれるツール、タスクランナーが必要となります。

  • Grunt
  • Gulp
  • npm-scripts (番外編)
    • Broccoli

昔は Grunt、その後は Gulp、そして現在は npm-scripts を使うのが主流となりつつあります。npm-scripts は npm 自身が持っている仕組みなので npm さえ入っていれば使えます。なぜ Grunt や Gulp が敬遠されるようになったのか、以下の記事が参考になります。

qiita.com

自分も以前はプロジェクトで Grunt や Gulp を使っていましたが、すこしアップデートしただけで突然動かなくなったということがよくありました。その経験から、今では極力 npm-scripts を使うようにしています。npm-scripts については以下の記事が非常に参考になります。

ics.media

3.JSモジュールの依存関係をまとめる ⇒ モジュールバンドラー

もともと JavaScript は言語仕様としてモジュールという仕組みは持っていませんでした。そのため、ロジックごとに別ファイルに切り出したり、モジュールパターンを使って名前空間を工夫したりして、頑張ってモジュール化を行っていました。

その後登場した Node.js には独自のモジュール機構があり(もともとは CommonJS 仕様に沿った実装だったけど独自に進化) require 構文を使って別モジュールをインポートすることができるようになりました。しかし require 構文はブラウザでは使えません。

さらにその後 ES2015(ES6) で import/export 構文が策定され、正式に言語レベルでモジュール機構がサポートされることになりました。しかし、仕様として決まっただけで、現在のブラウザの実装ではまだ import 構文を使用することができません。

そこで登場したのがモジュールバンドラーです。モジュールバンドラーは、require 構文および import 構文でインポートされたモジュール間の依存関係をまとめあげ、ブラウザ上で実行可能な1つのJSファイルに出力する機能を持っています。このおかげでもともと Node.js 用に書かれたライブラリでもブラウザ上で使うことができるようになったのです。

  • Browserify
  • webpack

Browserify が先に登場し、webpack が後発です。Browserify はエントリーポイントとなるJSファイルを1つしか作れないのに対して、webpack は複数のエントリーポイントに応じたJSファイルを出しわけることができます。

例えば画面A、B、Cがあったとして、Browserify の場合は、画面A、B、Cに対して1つのJSファイルしか出力できません。厳密には、Gulp などを併用することによって、それぞれ異なるファイルを出力するようにすることもできなくはありませんが、そのための環境を構築するのが複雑になります。対して webpack は、それ自身の仕組みで、各画面に応じたスクリプトファイルを簡単に出力することができます。そのため現在では webpack を使うのが好まれています。

以下のグラフは npm trends にて両者の比較を行った結果です。1年前は Browserify の方が優勢でしたが、ここ最近では webpack がダウンロード数で圧倒しており、Browserify の倍近くに迫る勢いです。webpack がいかに人気があるか分かると思います。

http://www.npmtrends.com/ f:id:tkiryu:20170207032537p:plain

そして今、どのツールを使うか?

  • パッケージマネージャー:npm ※あるいは Yarn
  • スクランナー:npm-scripts
  • モジュールバンドラー:webpack

が現時点において最もメジャーな Web フロントエンドツールスタックだと思います。

それじゃ ASP.NET Core 始めよう・・・

と思いきや、Visual Studio 2017 の ASP.NET Core のプロジェクトテンプレートを見てみると、

  • パッケージマネージャー:Bower(デフォルト)、npm を選択可能
  • スクランナー:なし(デフォルト) 、Grunt/Gulp を選択可能
  • モジュールバンドラー:なし

という現状で、現在のトレンドに合っていません。

次回

ということで、次回は ASP.NET Core プロジェクトで、npm, npm-scripts webpack を使用した最新のフロントエンドビルド環境を作るところから始めてみたいと思います。それでは。

TypeScript 2.1 から async/await が気軽に使えるようになっている件

– この記事は2017/02/03(Fri)現在の情報に基づいています –

なんで今更 async/await ?

TypeScript では既にバージョン 1.6 から async/await を使うことはできました。しかしこれまで、TypeScript から ES3/ES5 へ直接トランスパイルすることができませんでした。TypeScript に 加えて Babel も必要で、ビルド環境を作るのが若干面倒でした。

TypeScript コード ⇒ 一旦 ES6 コードに変換 ⇒ Babel を使って ES5 コードに変換

しかし、バージョン 2.1 から直接 ES3/ES5 コードに変換できるようになったので、より手軽に使えるようになったのです。

TypeScript で async/await を使ったサンプルコード

function sleep(milliseconds: number) {
  return new Promise<void>(resolve => {
    setTimeout(() => resolve(), milliseconds);
  });
}

async function main() {
  await sleep(1000);
  console.log('foo');
  await sleep(1000);
  console.log('bar');
  await sleep(1000);
  console.log('baz');
}

// Promise のメソッドチェーンで実現するとこうなる
// function main() {
//   sleep(1000)
//   .then(() => {
//     console.log('foo');
//     return sleep(1000);
//   })
//   .then(() => {
//     console.log('bar');
//     return sleep(1000);
//   })
//   .then(() => {
//     console.log('baz');
//   });
// }

sleep 関数は Promise オブジェクトを返す非同期関数ですが、async/await であたかも同期処理のように書くことができます。従来の方法よりはるかにスッキリかけるので、使わない手はありません!

ちなみに Pure ES5 だけで実現しようとすると・・・

function sleep2(milliseconds, callback) {
  setTimeout(function () {
    callback();
  }, milliseconds);
}

function main2() {
  sleep2(1000, function () {
    console.log('foo2');
    sleep2(1000, function () {
      console.log('bar2');
      sleep2(1000, function () {
        console.log('baz2');
      });
    });
  });
}

こうなります。3階層だからまだましですが、これが5、10と増えていくと・・・いわゆるコールバック地獄になります。。

実際に試したい人向け

こちらからダウンロードできます。

github.com

動作確認

ダウンロードしたプロジェクトの中の

index.html

をブラウザで開いて “execute main()” ボタンをクリックすると、コンソール上に1秒おきにメッセージが出力されることを確認できます。

f:id:tkiryu:20170205074732p:plain

ビルド方法

npm install

でTypeScript 2.1.5 をインストールして

npm run tsc

で TypeScript をトランスパイルします。tsc だけで ES3/ES5 に変換できているのが非常に楽ですね!

Yarn を使っている人は

yarn install
yarn run tsc

でもOKです。

最近のWebフロントエンド開発環境を Visual Studio 2015 (VS Code ではない)で構築する - Angular 2 webpack ビルド編 -

-- この記事は2016/11/22(Tue)現在の情報に基づいています --

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

  • ASP.NET MVC プロジェクト上に webpack を使った Angular 2 の ビルド環境を構築する
  • ビルドの実行は NPM Task runner を使うといい

という話です。

準備する環境

NPM Task runner は npm-scripts(package.json の scripts に記述されたコマンド)を Visual Studio 2015 上で実行できる拡張機能です。いちいちコマンドを手入力する必要がなく、マウス操作のみで実行できます。 さらに、プロジェクトを開いたタイミングや、プロジェクトのビルドの前/後に自動実行するように設定することもできるので、とても便利です。

1つ注意点として、Visual Studio 2015 は Node.js をオプションでインストールできますが、バージョンが古いため、最新バージョンを使いたい場合は別途 Node.js をインストール必要があります。しかし、インストールしただけではパスが通っていないため Visual Studio 2015 から使うことができません。以下を参考に、パスの設定を行います。

qiita.com

チュートリアルに沿って作ってみる

Angular 2 のドキュメントに webpack を使って構築するためのチュートリアルがあるので、それに沿って環境を構築していきます。

angular.io

1.設定ファイルの作成

設定系のファイルだけでこれだけの数を作成しないといけません。Webフロントエンド開発環境は本当に複雑になりました。。

  • package.json // npm パッケージ
  • tsconfig.json // TypeScript 用設定ファイル
  • webpack.config.js // webpack でビルドするために必要な設定ファイル
    • config/webpack.common.js // 共通
    • config/webpack.dev.js // 開発
    • config/webpack.prod.js // 本番
    • config/helper.js // path を解決するためのヘルパー関数
  • karma.conf.js // karma でテストを実行するために必要な設定ファイル
    • config/karma.conf.js // karma 自体の設定ファイル
    • config/webpack.test.js // テストに webpack を使用するための設定ファイル
    • config/karma-test-shim.js //

f:id:tkiryu:20161118003554p:plain

2.アプリケーションのエントリポイントの作成

文字通り、アプリケーションが最初に実行される場所を作ります。

  • src/index.html
  • src/main.ts // アプリケーションコード
  • src/vendor.ts // ベンダーコード
  • src/polyfills.ts // ポリフィルコード

f:id:tkiryu:20161118130525p:plain

3.コンポーネントの作成

ようやく Angular 2 らしいコードが現れました。コンポーネント単位で html, js, css をまとめて1つのフォルダで管理します。

  • src/app/app.module.ts // モジュール
  • src/app/app.component.ts // ロジック
  • src/app/app.component.html // テンプレート
  • src/app/app.component.css // スタイル
  • src/app/app.component.spec.ts // コンポーネントに対するテストコード

f:id:tkiryu:20161118130851p:plain

以上で、必要なファイルの作成は終わりです。

実行確認

必要なファイルが揃ったので、実際にうまく動作するか確認していきます。

1.npm install の実行

上記までは package.json の内容をチュートリアルからコピペしただけなので、実際にパッケージのダウンロードが必要です。以前の - npm パッケージインストール編 -

tkiryu.hatenablog.com

で紹介した Package Installer の機能でもインストールができますが、今回新たに追加した NPM Task runner の拡張機能を使ってみたいと思います。

package.json を右クリック > タスクランナー エクスプローラー を選択します(NPM Task runner を入れたことで使えるようになった機能です)。

f:id:tkiryu:20161119004623p:plain

すると、以下のように タスクランナー エクスプローラーのペインが現れます。

f:id:tkiryu:20161119005744p:plain

package.json > Defaults > install を右クリック > 実行 を選択します。

f:id:tkiryu:20161119005848p:plain

すると、npm install が実行され、パッケージのインストールが始まります。かなり多くのパッケージをインストールするのでそれなりに時間がかかります。問題なくインストールが終わると以下のように「プロセスコードはコード 0 で終了しました。」と表示されます。

f:id:tkiryu:20161121085959p:plain

2.npm start の実行

インストールが完了したので、早速動かしてみます。

package.json > Defaults > start を右クリック > 実行 を選択します。

f:id:tkiryu:20161121125610p:plain

タブに「start(実行中)」と表示されています。ローカルサーバーがうまく動作しているようです。

f:id:tkiryu:20161121125741p:plain

conf/webpack.dev.js の publicPath プロパティに指定した URL でアクセスできる(ログにも表示されています)ので、http://localhost:8080/ にアクセスしてみると、問題なく表示されていることが確認できました。

f:id:tkiryu:20161121125939p:plain

3.npm test の実行

続いてテストの実行です。

package.json > Defaults > test を右クリック > 実行 を選択します。

f:id:tkiryu:20161121222149p:plain

無事テストにパスしました。

f:id:tkiryu:20161121222259p:plain

4.npm build の実行

最後にプロダクションコードとしてビルドしてみます。

package.json > Custom > build を右クリック > 実行 を選択します。

f:id:tkiryu:20161121224932p:plain

ビルド成功しました。

f:id:tkiryu:20161121225130p:plain

ビルドしたファイルは dist フォルダ配下に出力されています。

f:id:tkiryu:20161121230520p:plain

以上で、全ての npm-scripts が問題なく実行できることが確認できました。

npm-scripts の VSバインディング

上記では npm-scripts を手動で実行しましたが、Visual Studio 上のイベントをトリガーにして自動実行することもできます。

バインドできるのは以下の4つのイベントです。

  • ビルド前:ソリューションのビルド前
  • ビルド後:ソリューションのビルド後
  • 消去:ソリューションのクリーン時
  • プロジェクトを開く:プロジェクトを開いた時

以下は

  • 「ビルド後」で npm test と npm build

をそれぞれバインドした状態になっています。

f:id:tkiryu:20161122015738p:plain

まとめと今後の課題

ひとまず、ASP.NET MVC プロジェクト上で Angular 2 を動かすことができるようになりました。作成したプロジェクトは GitHub にアップしましたのでご自由にお試しください。

github.com

しかし、課題もあります。

  • プロジェクト内に、フロントエンドとバックエンドのフォルダ・ファイルが入り乱れていて、把握しづらい。

f:id:tkiryu:20161121235638p:plain

などです。

フォルダ構成の整理や、ASP.NET MVC とどう調和させるかを踏まえて、ブラッシュアップさせていければと思います。

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