CoffeeScript を ASP.NET MVC 4 で使用する
CoffeeScript は、今注目を浴びている JavaScript を生成するための言語で、シンプルで洗練された構文で JavaScript (の素) を記述していくことができます。
詳細は下記などをご参照ください。
少し前に こちらのブログ記事 で WebMatrix 2 で CoffeeScript を使用する方法をご紹介しましたが、今回は Visual Studio 2010 や Visual Studio 2012 と ASP.NET MVC 4 で CoffeeScript を使用する方法をご紹介します。
※ 本投稿は CoffeeScript Custom Processor in ASP.NET MVC 4 Beta の記事を参考に、MVC 4 RC で変更になった部分を修正しています。
● CoffeeScript コンパイラーのインストール
Visual Studio 2010 / 2012 で ASP.NET MVC 4 のプロジェクトを作成した後、NuGet パッケージ マネージャーから、CoffeeScript コンパイラーをインストールします。NuGet ギャラリーには、何種類かの CoffeeScript コンパイラーがリストされていますが、ここでは CoffeeSharp を使用しました。
※ パッケージ マネージャー コンソール では下記のコマンドでインストールできます。
● カスタム Bundle 処理用クラスの追加
ASP.NET MVC 4 では、JavaScript や CSS などのファイルをサーバーサイドで 1 ファイルに結合した上に圧縮処理 (縮小化) をおこない、Web ページのペイロードを削減する仕組みが用意されています。この Bundle 処理に CoffeeSharp コンパイラーを使って CoffeeScript をコンパイルするカスタム処理を追加し、ページのロード時にサーバーサイドでダイナミックに CoffeeScript をコンパイルする実装を行います。
これには下記のクラスをプロジェクトに追加します。
[CoffeeCompiler.cs]
1: using System;
2: using System.Web;
3: using System.Web.Optimization;
4: using System.IO;
5:
6: namespace MvcCoffee
7: {
8: public class CoffeeCompiler : IBundleTransform
9: {
10: public void Process(BundleContext context, BundleResponse response)
11: {
12: var coffeeScriptEngine = new CoffeeSharp.CoffeeScriptEngine();
13: string compiledCoffeeScript = String.Empty;
14:
15: foreach (var file in response.Files)
16: {
17: using (var reader = new StreamReader(file.FullName))
18: {
19: compiledCoffeeScript +=
20: coffeeScriptEngine.Compile(reader.ReadToEnd());
21: reader.Close();
22: }
23: }
24:
25: response.Content = compiledCoffeeScript;
26: response.ContentType = "text/javascript";
27: response.Cacheability = HttpCacheability.Public;
28: }
29: }
30: }
※ 今回は、CoffeeCompiler クラスでは CoffeeScript から生成された JavaScript の縮小処理 (Minify) は実装していませんが、IBundleTransform ではなく、JsMinify クラスを基底とすることで縮小機能も実装することができるでしょう。
そして、プロジェクトの App_Start フォルダにある BundleConfig.cs の RegisterBundles メソッドに下記の記述を追加して、CoffeeCompiler クラスによる Bundle 処理を追加します。
[App_Start\BundleConfig.cs]
1: namespace MvcCoffee
2: {
3: public class BundleConfig
4: {
5: public static void RegisterBundles(BundleCollection bundles)
6: {
7:
8: ...
9:
10: var coffeeBundle = new DynamicFolderBundle("coffee",
11: "*.coffee",
12: new CoffeeCompiler());
13: bundles.Add(coffeeBundle);
14:
15: ...
16:
17: }
18: }
19: }
● CoffeeScript をプロジェクトへ追加
使用する CoffeeScript ファイルをプロジェクトの任意のフォルダーに追加します。今回は Scripts/Coffee フォルダーに Latte.coffee ファイルを追加しました。
[Latte.coffee]
1: # Class
2: class Human
3: constructor: (@name) ->
4:
5: class Chack extends Human
6: Name: -> alert @name
7:
8: me = new Chack("akira")
9: me.Name()
ここでは、クラス Human とその派生クラス Chack を記述してみました。構文の詳細は coffeescript.org などをご参照ください。
● スクリプト タグの記述
最後に、CoffeeScript をコンパイルした JavaScript を読み込む Script タグをビュー (.cshtml) に記述します。
ASP.NET MVC 4 では、Scripts.Render ヘルパーを使用して下記のように記述可能です。
[_Layout.cshtml]
1: <!DOCTYPE html>
2: <html lang="ja">
3: <head>
4: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5: <meta charset="utf-8" />
6: <title>@ViewBag.Title</title>
7: <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
8: <meta name="viewport" content="width=device-width" />
9: @Styles.Render("~/Content/css")
10: @Scripts.Render("~/bundles/modernizr")
11: ...
12: @Scripts.Render("~/Scripts/Coffee/coffee")
13: ...
※ カスタム処理として追加した CoffeeScript に関しては、今回は縮小機能を実装していませんので縮小化は行われませんが、標準の Bundle 処理では、この Script.Render ヘルパーによってファイルの結合・縮小処理を使用することができます。但し、デバッグの際の利便性を考慮して、Web.config の compilation 要素の debug 属性値が true の場合は結合・縮小処理が有効になりません。デバッグなどが終わり運用に移行する際などには、この設定を変更して結合・縮小処理を有効にしてください。
1: <system.web>
2: <compilation debug="false" targetFramework="4.0" />
● 実行・動作確認
これで、プロジェクトをビルドしアプリケーションを実行すると、サーバーサイドでダイナミックに CoffeeScript がコンパイルされ、生成された JavaScript がクライアントサイドにロードされます。
コンパイルされた JavaScript コード
1: (function() {
2: var Chack, Human, me,
3: __hasProp = {}.hasOwnProperty,
4: __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
5:
6: Human = (function() {
7:
8: Human.name = 'Human';
9:
10: function Human(name) {
11: this.name = name;
12: }
13:
14: return Human;
15:
16: })();
17:
18: Chack = (function(_super) {
19:
20: __extends(Chack, _super);
21:
22: Chack.name = 'Chack';
23:
24: function Chack() {
25: return Chack.__super__.constructor.apply(this, arguments);
26: }
27:
28: Chack.prototype.Name = function() {
29: return alert(this.name);
30: };
31:
32: return Chack;
33:
34: })(Human);
35:
36: me = new Chack("akira");
37:
38: me.Name();
39:
40: }).call(this);
実行結果
◆◆◆
CoffeeScript の記述と、そこから生成された JavaScript を比較すると、その違いは歴然ですね。私も CoffeeScript に関しては全くの初心者ですが、CoffeeScript を習得して使用するメリットは十分にあるのではないでしょうか。
また、Visual Studio 2010 や Visual Studio 2012 で使用できる NuGet パッケージマネージャーや、ASP.NET MVC 4 の拡張性を活かして、CoffeeScript のような拡張言語も容易に使用することができます。ぜひお試しくださいませ。