Grunt は、スクリプトの縮小、TypeScript のコンパイル、コード品質の "lint" ツール、CSS プリプロセッサなど、クライアント開発をサポートするために必要なほとんどの反復作業を自動化する JavaScript タスク ランナーです。 Grunt は、Visual Studio で完全にサポートされています。
この例では、空の ASP.NET Core プロジェクトを開始点として使用して、クライアントのビルド プロセスをゼロから自動化する方法を示します。
完成した例では、ターゲットの展開ディレクトリのクリーンアップ、JavaScript ファイルの結合、コード品質の確認、JavaScript ファイル コンテンツの圧縮、および Web アプリケーションのルートへの展開を行います。 次のパッケージを使用します。
grunt:Grunt タスク ランナー パッケージ。
grunt-contrib-clean:ファイルまたはディレクトリを削除するプラグイン。
grunt-contrib-jshint:JavaScript コードの品質を確認するプラグイン。
grunt-contrib-concat:ファイルを 1 つのファイルに結合するプラグイン。
grunt-contrib-uglify:サイズを小さくするために JavaScript を縮小するプラグイン。
grunt-contrib-watch:ファイル アクティビティを監視するプラグイン。
アプリケーションの準備
最初に、空の新しい Web アプリケーションを設定し、TypeScript サンプル ファイルを追加します。 TypeScript ファイルは、既定の Visual Studio 設定を使用して JavaScript に自動的にコンパイルされ、Grunt を使用して処理する未加工の素材になります。
Visual Studio で、新しい
ASP.NET Web Applicationを作成します。[新しい ASP.NET プロジェクト] ダイアログで、ASP.NET Core の [空] テンプレートを選択し、[OK] ボタンをクリックします。
ソリューション エクスプローラーで、プロジェクトの構造を確認します。
\srcフォルダーには、空のwwwrootノードとDependenciesノードが含まれます。
TypeScriptという名前の新しいフォルダーをプロジェクト ディレクトリに追加します。ファイルを追加する前に、Visual Studio で TypeScript ファイルに対して [保存時にコンパイル] オプションがオンになっていることを確認してください。 [ツール]>[オプション]>[テキスト エディター]>[TypeScript]>[プロジェクト] に移動します。
TypeScriptディレクトリを右クリックし、コンテキスト メニューで > の順に選択します。 [JavaScript ファイル] 項目を選択し、ファイルにTastes.tsという名前を指定します (*.ts 拡張子に注意してください)。 次の TypeScript コード行をファイルにコピーします (保存すると、新しいTastes.jsファイルが JavaScript ソースと共に表示されます)。enum Tastes { Sweet, Sour, Salty, Bitter }2 つ目のファイルを TypeScript ディレクトリに追加し、
Food.tsという名前を指定します。 次のコードをファイルにコピーします。class Food { constructor(name: string, calories: number) { this._name = name; this._calories = calories; } private _name: string; get Name() { return this._name; } private _calories: number; get Calories() { return this._calories; } private _taste: Tastes; get Taste(): Tastes { return this._taste } set Taste(value: Tastes) { this._taste = value; } }
npm の構成
次に、grunt タスクと grunt-tasks をダウンロードするように npm を構成します。
ソリューション エクスプローラーで、プロジェクトを右クリックし、コンテキスト メニューから [追加>新しい項目 ] を選択します。 npm 構成ファイル項目を選択し、既定の名前のままにして
package.jsonし、[追加] ボタンをクリックします。package.jsonファイルで、devDependenciesオブジェクトの中かっこの内側に「grunt」と入力します。 Intellisense の一覧から [grunt] を選択し、Enter キーを押します。 Visual Studio によって grunt パッケージ名が引用され、コロンが追加されます。 コロンの右側で、Intellisense の一覧の一番上にある最新の安定バージョンのパッケージを選択します (Intellisense が表示されない場合はCtrl-Spaceキーを押します)。
Note
npm では、 セマンティック バージョン管理を 使用して依存関係を整理します。 セマンティック バージョニングは SemVer とも呼ばれ、<メジャー>.<マイナー>.<パッチ> の番号設定によってパッケージを識別するものです。 Intellisense では、いくつかの共通の選択肢だけを表示することで、セマンティック バージョニングが簡略化されています。 Intellisense の一覧の一番上にある項目 (上の例では 0.4.5) は、最新の安定バージョンのパッケージと見なされます。 キャレット (^) 記号は最新のメジャー バージョンと一致し、チルダ (~) は最新のマイナー バージョンと一致します。 SemVer が提供する完全な表現力のガイドとして、 npm semver バージョンパーサーリファレンス を参照してください。
次の例に示すように、clean、jshint、concat、uglify、watch に対して grunt-contrib-* パッケージを読み込むよう、さらに依存関係を追加します。 バージョンは例と一致している必要はありません。
"devDependencies": { "grunt": "0.4.5", "grunt-contrib-clean": "0.6.0", "grunt-contrib-jshint": "0.11.0", "grunt-contrib-concat": "0.5.1", "grunt-contrib-uglify": "0.8.0", "grunt-contrib-watch": "0.6.1" }package.jsonファイルを保存します。
各 devDependencies 項目のパッケージが、各パッケージに必要なすべてのファイルと共にダウンロードされます。
ソリューション エクスプローラーで [すべてのファイルを表示] ボタンを有効にすると、node_modules ディレクトリ内のパッケージ ファイルを確認できます。
Note
必要に応じて、ソリューション エクスプローラーで Dependencies\npm を右クリックし、 [パッケージの復元] メニュー オプションを選択することで、依存関係を手動で復元できます。
Grunt の構成
Grunt は、Gruntfile.js という名前のマニフェストを使用して構成されます。このマニフェストでは、手動で実行したり、Visual Studio のイベントに基づいて自動的に実行されるように構成したりできるタスクの定義、読み込み、および登録が行われます。
プロジェクトを右クリックし、 [追加]>[新しい項目] を選択します。 [JavaScript ファイル] 項目テンプレートを選択し、名前を
Gruntfile.jsに変更して、 [追加] ボタンをクリックします。次のコードを
Gruntfile.jsに追加します。initConfig関数によって各パッケージのオプションが設定され、モジュールの残りの部分によってタスクの読み込みと登録が行われます。module.exports = function (grunt) { grunt.initConfig({ }); };次の
initConfigの例に示すように、clean関数の内部にGruntfile.jsタスクのオプションを追加します。cleanタスクで、ディレクトリ文字列の配列が受け入れられます。 このタスクにより、wwwroot/lib からファイルが削除され、 /temp ディレクトリ全体が削除されます。module.exports = function (grunt) { grunt.initConfig({ clean: ["wwwroot/lib/*", "temp/"], }); };initConfig関数の下に、grunt.loadNpmTasksの呼び出しを追加します。 これにより、タスクが Visual Studio から実行できるようになります。grunt.loadNpmTasks("grunt-contrib-clean");Gruntfile.jsを保存します。 ファイルは次のスクリーンショットのようになります。
Gruntfile.jsを右クリックし、コンテキスト メニューで [タスク ランナー エクスプローラー] を選択します。 [タスク ランナー エクスプローラー] ウィンドウが開きます。
cleanの [タスク] の下に が表示されていることを確認します。
[clean] タスクを右クリックし、コンテキスト メニューで [実行] を選択します。 コマンド ウィンドウに、タスクの進行状況が表示されます。
Note
クリーンアップするファイルまたはディレクトリはまだありません。 必要に応じて、ソリューション エクスプローラーでこれらを手動で作成し、clean タスクをテストとして実行できます。
initConfig関数で、次のコードを使用してconcatのエントリを追加します。srcプロパティの配列には、結合するファイルが、結合する順序でリストされます。destプロパティにより、生成された結合ファイルへのパスが割り当てられます。concat: { all: { src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'], dest: 'temp/combined.js' } },Note
上記のコードの
allプロパティは、ターゲットの名前です。 ターゲットは、複数のビルド環境が許可されるいくつかの Grunt タスクで使用されます。 IntelliSense を使用して組み込みのターゲットを表示するか、独自のターゲットを割り当てることができます。次のコードを使用して、
jshintタスクを追加します。jshint
code-qualityユーティリティは、temp ディレクトリにあるすべての JavaScript ファイルに対して実行されます。jshint: { files: ['temp/*.js'], options: { '-W069': false, } },Note
オプション "-W069" は、JavaScript でドット表記の代わりに角かっこ構文 (たとえば、
Tastes["Sweet"]の代わりにTastes.Sweet) を使用してプロパティが割り当てられると、jshint によって生成されるエラーです。 このオプションを選択すると、残りのプロセスを続行できるように警告がオフになります。次のコードを使用して、
uglifyタスクを追加します。このタスクは、一時ディレクトリにある
combined.jsファイルをミニフィグし、標準の名前付け規則 <ファイル名>.min.jsに従って wwwroot/lib に結果ファイルを作成します。uglify: { all: { src: ['temp/combined.js'], dest: 'wwwroot/lib/combined.min.js' } },grunt.loadNpmTasksを読み込むgrunt-contrib-cleanの呼び出しの下で、次のコードを使用して、jshint、concat、および uglify に対して同じ呼び出しを含めます。grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify');Gruntfile.jsを保存します。 ファイルは次の例のようになります。
タスク ランナー エクスプローラーの [タスク] 一覧に、
clean、concat、jshint、およびuglifyの各タスクが含まれることに注意してください。 各タスクを順番に実行し、ソリューション エクスプローラーの結果を確認します。 各タスクはエラーなしに実行されるはずです。
concat タスクでは、新しい
combined.jsファイルが作成され、temp ディレクトリに格納されます。jshintタスクは単に実行されるだけで、出力は生成されません。uglifyタスクでは、新しいcombined.min.jsファイルを作成し、それを wwwroot/lib に配置します。 完了すると、ソリューションは次のスクリーンショットのようになります。
Note
各パッケージのオプションの詳細については、https://www.npmjs.com/ にアクセスし、メイン ページの検索ボックスでパッケージ名を検索してください。 たとえば、grunt-contrib-clean パッケージを参照して、すべてのパラメーターを説明するドキュメント リンクを取得できます。
すべてをまとめる
Grunt registerTask() メソッドを使用して、一連のタスクを特定のシーケンスで実行します。 たとえば、上記の手順の例を clean -> concat -> jshint -> uglify の順に実行するには、次のコードをモジュールに追加します。 このコードは、initConfig の外部で loadNpmTasks() 呼び出しと同じレベルに追加する必要があります。
grunt.registerTask("all", ['clean', 'concat', 'jshint', 'uglify']);
新しいタスクが、タスク ランナー エクスプローラーの [エイリアス タスク] の下に表示されます。 このタスクは、他のタスクと同様に右クリックして実行できます。
all タスクでは、clean、concat、jshint、uglify が順番に実行されます。
変更の監視
watch タスクでは、ファイルとディレクトリが監視されます。 watch によって変更が検出されると、タスクが自動的にトリガーされます。 次のコードを initConfig に追加して、TypeScript ディレクトリ内の *.js ファイルへの変更を監視します。 JavaScript ファイルが変更さると、watch によって all タスクが実行されます。
watch: {
files: ["TypeScript/*.js"],
tasks: ["all"]
}
タスク ランナー エクスプローラーで loadNpmTasks() タスクを表示するよう、watch の呼び出しを追加します。
grunt.loadNpmTasks('grunt-contrib-watch');
タスク ランナー エクスプローラーで [watch] タスクを右クリックし、コンテキスト メニューで [実行] を選択します。 実行中の watch タスクを表示するコマンド ウィンドウに、"Waiting…" メッセージが表示されます。 TypeScript ファイルの 1 つを開き、スペースを追加して、ファイルを保存します。 これにより、watch タスクがトリガーされ、他のタスクがトリガーされて順番に実行されます。 次のスクリーンショットは、サンプルの実行を示しています。
Visual Studio イベントへのバインド
Visual Studio で作業するたびに手動でタスクを開始する場合を除き、 [ビルド前] 、 [ビルド後] 、 [クリーン] 、および [プロジェクトを開く] の各イベントにタスクをバインドします。
watch をバインドして、Visual Studio が開くたびに実行されるようにします。 タスク ランナー エクスプローラーで [watch] タスクを右クリックし、コンテキスト メニューで [バインド]>[プロジェクトを開く] を選択します。
プロジェクトをアンロードして再読み込みします。 プロジェクトが再度読み込まれると、watch タスクの実行が自動的に開始されます。
まとめ
Grunt は、クライアントによってビルドされたほとんどのタスクを自動化するために使用できる強力なタスク ランナーです。 Grunt は npm を利用してパッケージを提供し、Visual Studio とのツール統合を備えています。 Visual Studio のタスク ランナー エクスプローラーでは、構成ファイルへの変更が検出され、タスクの実行、実行中のタスクの表示、および Visual Studio イベントへのタスクのバインドを行うための便利なインターフェイスが提供されます。
ASP.NET Core