網頁

ASP.NET MVC 4 RC 的 JavaScript / CSS 的打包與壓縮(Bundling and Minification)

Kendo UI Grid 參考來源

本篇參考黑暗執行緒「在ASP.NET MVC 4中使用Kendo UI Grid」一文將 C# 語法轉為 VB 語法練習。在練習實作期間,發現了一些差異,寫下留個記錄。另外我之前介紹過一套 NuGet:SquishIt 套件,來進行 JavaScript 與 CSS 的打包與壓縮,在 ASP.NET MVC 4 RC 中本身就已經是實作此功能,以下大部分都是以討 Bundling / Minification 這兩個功能為主。

Kendo UI Grid for Visual Basic 實作

  1. 新增一個【ASP.NET MVC 4 Internet 專案 for ASPX】(我使用 Visual Studio 2012 RC 實作)。這裡我說明一下,在最新版 Visual Studio 2012 RC 版本中,ASP.NET MVC 4 有 6 個 Project Template,分別:

    1. Empty
    2. Basic
    3. Internet Application
    4. Intranet Application
    5. Mobile Application
    6. Web API

    還有一種 Single Page Application 在 ASP.NET MVC 4 Beta 時出現,但在 Visual Studio 2012 RC 版的樣版中消失了,原因請參考 Single Page Application 網頁說明。Empty / Basic 會給你很乾淨的專案樣版,沒有辦法立即使用,必須進行相當手續設定及新增 Controller / Action / View 等步驟,想要立即能有可執行測試的專案,還是 Internet Application 比較合適些。

  2. 使用 NuGet 安裝 KendoUIWebKendoGridBinder
    • Install-Package KendoUIWeb
    • Install-Package KendoGridBinder

    安裝好之後,你可以在【Content\kendo\2012.1.322】發現必須的 CSS 檔案,在【Scripts\kendo\2012.1.322】發現必須的 JavaScript 檔案。

  3. 到【App_Start\BundleConfig.vb】新增 Kendo UI 的 CSS 與 JavaScript 的打包壓縮設定:

    ' Kendo UI Script and CSS
    bundles.Add(New ScriptBundle("~/bundles/Kendo").Include(
                "~/Scripts/kendo/2012.1.322/kendo.web.min.js"))
    
    bundles.Add(New StyleBundle("~/Content/kendo/2012.1.322/css").Include(
                "~/Content/kendo/2012.1.322/kendo.common.min.css",
                "~/Content/kendo/2012.1.322/kendo.blueopal.min.css"))
    

    這裡我測試的結果與黑暗執行緒在步驟4有些差異,我測試結果在路徑含 "*/2012.1.322/*" 下是可以正常進行 Styles.Render()。

    我們順便了解一下目前 ASP.NET MVC 4 RC 裡的打包與壓縮功能。bundles.add() 是加入集合,我們可以指定要新增 ScriptBundle 或 StyleBundle,這裡我們可以 Bundle 的相關檔案進行群組化設定,ScriptBundle("~/VirtualPath/...") 或 StyleBundle("~/VirtualPath/...") 是一個虛擬路徑,也是一個群組名稱。然後透過 .Include() 方法將你將打包及縮壓的 JavaScript 與 CSS 檔案一一設定進來。你可以打開【App_Start\BundleConfig.vb】檔案,裡面就預設多組的 Bundle 群組化設定,這裡只是設定並不會產生作用,還必須進行兩個步驟。

    這裡的群組化設定可以給我們帶來很大的方便,例如,我以前會為了 jQuery 的更新傷腦筋,方法很多種,最笨就是開頁面改版本號(例如,jQuery-1.2.6.min.js 更新為 jQuery-1.7.2.min.js),好一點用同名稱把檔案覆寫,例如,jQeruy.min.js(更新版) → 覆寫 jQuery.min.js(舊版),但同名稱複寫也有問題,不用多,二個月之後,我問你某個頁面使用的是那一版本的 jQuery,你一定無法馬上回答。你看一下預設規則第一條:

    bundles.Add(New ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-1.*"))
    

    在 ASP.NET MVC 4 RC 裡的 Scripts 目錄之下,你會發現怎麼預設沒有加入 jQuery-1.6.2.min.js,原因就在上面,現在 ASP.NET MVC 4 RC 會自動幫你進行打包及壓縮的動作,再來,今天我要更新至 jQuery-1.7.2.js,我只需要把檔案下載回來放到 Scripts 目錄下,然後移除 jQuery-1.6.2.js,立即所有有引用的頁面都會執行新版本的 jQuery。所以下一步如何使用我們設定好的群組。

  4. 在 Site.Master 選擇要使用群組

    <%: Styles.Render("~/Content/themes/base/css", "~/Content/css", "~/Content/kendo/2012.1.322/css")%>
    <%: Scripts.Render("~/bundles/jquery", "~/bundles/Kendo")%>
    

    Sytles.Render() 可設定多組 StyleBundle() 群組名稱,這裡的名稱必須與【App_Start\BundleConfig.vb】設定的名稱一致,同理,Scripts.Render() 可設定多組 ScriptBundle() 群組名稱,這裡的名稱必須與【App_Start\BundleConfig.vb】設定的名稱一致。不管是在 Site.Master 或個別的頁面,我們所引用不是含絕對或相對路徑的檔案,而是一組一組設定好的 Script 和 CSS 群組設定,這把 CSS 與 JavaScript 更進一步的從頁面抽離出來。這是使用 Bundle 的第一步,如果你現在按【Ctrl + F5】開啟網頁去看原始碼,並不會有 Bundling / Minification 的效果出現,每個 CSS 與 JavaScript 都還是獨立出現,想要測試第二步,必須取消 Debug 模式:

    <system.web>
      <compilation debug="false" targetFramework="4.5" />
      <!-- 略 -->
    

    修改 Web.config 裡 compilation 的 debug="false",重新執行專案,你就能看到 Bundling / Minification 的效果。以我預設專案的首頁而言,從原始碼來看:

    <link href="/Content/css?v=ZAyqul2u_47TBTYq93se5dXoujE0Bqc44t3H-kap5rg1" rel="stylesheet" type="text/css" />
    <link href="/Content/kendo/2012.1.322/css?v=38Py9EERkWohK68DMMP7YFibk9PaNmvXQ1laiCvlf_I1" rel="stylesheet" type="text/css" />
    <script src="/bundles/modernizr?v=EuTZa4MRY0ZqCYpBXj_MhJfFJU2QBDf0xGrV_p1fHME1" type="text/javascript"></script>
    <script src="/bundles/jquery?v=LsMCe96-p5oJgNHYGGB4L5iBU-9lwZIN8ggQ5ePtESY1" type="text/javascript"></script>
    <script src="/bundles/Kendo?v=sWkvuxag9ZtGWuMifh06hRbmok4u1R2cvxGMnHvgc1k1" type="text/javascript"></script>
    

    ASP.NET MVC 4 RC 會產生虛擬路徑及打包壓縮好的檔案回傳(頁面的第一次瀏覽會慢一點點)。透過了【App_Start\BundleConfig.vb】設定檔的幫忙,我們在高內聚低耦合的目標上更上一層樓。頁面裡連 CSS 與 JavaScript 的引用都抽離出來。有沒有覺得 ASP.NET MVC 真的好讚。

  5. 在 Model 目錄新增 SimMemberInfo.vb 產生測試資料:

    Imports System.Drawing
    Imports System.Reflection
    
    ''' <summary>
    ''' 模擬資料物件
    ''' </summary>
    Public Class SimMemberInfo
        ' 會員編號
        Public UserNo As String
        ' 會員名稱
        Public UserName As String
        ' 註冊日期
        Public RegDate As DateTime
        ' 累積點數
        Public Points As Integer
    
        ' 模擬資料來源
        Public Shared SimuDataStore As List(Of SimMemberInfo) = Nothing
    
        Shared Sub New()
            Dim rnd As New Random()
    
            ' 從 System.Drawing 裡的 Color 型別取出顏色名稱
            Dim colorNames() As String = GetType(Color).
                GetProperties(BindingFlags.Static Or BindingFlags.Public).
                Select(Function(o) o.Name).
                ToArray()
    
            ' 產生資料
            SimuDataStore = colorNames.Select( _
                Function(cn) New SimMemberInfo() With {
                    .UserNo = String.Format("C{0:00000}", rnd.Next(99999)),
                    .UserName = cn,
                    .RegDate = DateTime.Today.AddDays(-rnd.Next(1000)),
                    .Points = rnd.Next(9999)}).ToList()
        End Sub
    End Class
    
  6. 在 HomeController.vb 新增兩個 Action:

    Imports KendoGridBinder
    
    Public Class HomeController
        Inherits System.Web.Mvc.Controller
    
        ' ... 略 ...
    
        Function KendoGrid() As ActionResult
            Return View()
        End Function
    
        Function Grid(request As KendoGridRequest, keywd As String) As JsonResult
            Dim result = SimMemberInfo.SimuDataStore.Where(
                Function(o) String.IsNullOrEmpty(keywd) OrElse o.UserName.Contains(keywd))
    
            Return Json(New KendoGrid(Of SimMemberInfo)(request, result))
        End Function
    End Class
    

    注意,必須引用Imports KendoGridBinder,

  7. 新增 KendoGrid.aspx 的 View,View 部分沒有差異,請直接到原文網站複製步驟6的相關程式碼測試。

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。