[MVC]JavascriptExtensionV1.1自動使用最新版的Javascript檔案

  • 8376
  • 0
  • Web
  • 2011-12-26

因為最近jquery頻頻更新,每次使用Nuget更新完後,又要改一些_Layout,忘了改又會照成頁面錯誤,而且我們的專案是使用預編譯,所以_Layout也是在dll中,為了更新View使用的javascript版本,我要改View、編譯、佈署dll與js檔,實在有夠麻煩的,所以就想了一個小方法,只要把js檔放在~/Scripts下,程式執行時,就會搜尋資料夾使用最新版的js檔,減少更新的步驟,也減少出錯的可能。

因為最近jquery頻頻更新,每次使用Nuget更新完後,又要改一些_Layout,忘了改又會照成頁面錯誤,而且我們的專案是使用預編譯,所以_Layout也是在dll中,為了更新View使用的javascript版本,我要改View、編譯、佈署dll與js檔,實在有夠麻煩的,所以就想了一個小方法,只要把js檔放在~/Scripts下,程式執行時,就會搜尋資料夾使用最新版的js檔,減少更新的步驟,也減少出錯的可能。

 

使用範例

用法跟MVC一模一樣,只要將@Url.Content換成@Url.Script,將檔名版本部分的地方用替換成 * 符號,且不用打~/Scripts/因為程式預設(本來想寫多載的,但後來想想在MVC下不會換路徑,就不寫活了)。

<!--使用jquery的min版最新版-->
<script src="@Url.Script("jquery-*.min.js")" type="text/javascript"></script>

<!--使用jquery的min版最新版,但限定在1.6中最新版-->
<script src="@Url.Script("jquery-1.6.*.min.js")" type="text/javascript"></script>

<!--使用fancyboxy的pack版最新版-->
<script src="@Url.Script("jquery.fancybox-*.pack.js")" type="text/javascript"></script>

MVC 2.0寫法
<script src="<%=Url.Script("jquery-1.6.*.min.js")%>" type="text/javascript"></script>

注意:找不到檔案我是丟Expection。

image

原始碼

using System.Text.RegularExpressions;
using System.Runtime.Caching;

namespace System.Web.Mvc
{
    public static class JavascriptExtensions
    {
        /// <summary>
        /// 使用最新版的Script,規則是name-version.extension,輸入時請轉成name-*.extension,如jquery-*.min.js。
        /// 只會找Scripts資料夾下
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="script">Script名稱,如:jquery-*.min.js</param>
        /// <returns></returns>
        public static string Script(this UrlHelper helper, string scriptPattern)
        {
            //TODO 下一版 要監視資料夾,有變動要清快取

            //使用.Net 4.0的System.Runtime.Caching,記得加入參考
            string path = MemoryCache.Default[scriptPattern] as string;
            if (path == null)
            {
                //如果沒有就不需要換
                if (scriptPattern.IndexOf('*') > -1)
                {
                    string scriptRegex = scriptPattern.Replace("*", "[.0-9]+");
                    string root = helper.RequestContext.HttpContext.Server.MapPath("~/Scripts/");

                    foreach (var filePath in Directory.EnumerateFiles(root, scriptPattern, SearchOption.AllDirectories))
                    {
                        //先用Directory過濾後再用Regex過濾
                        string filename = filePath.Remove(0, root.Length);
                        filename = filename.Replace(@"\\", "/"); //怕有子目錄

                        if (!Regex.IsMatch(filename, scriptRegex))
                        {
                            continue;
                        }

                        if (path == null)
                        {
                            path = filename; //第一次
                        }
                        else if (path.CompareTo(filename) < 0)
                        {
                            path = filename; //比大小
                        }
                    }

                    if (path == null)
                    {
                        throw new ArgumentException("找不到檔案,Pattern為:" + scriptPattern);
                    }

                    //換成虛擬路徑
                    path = helper.Content("~/Scripts/" + path);
                }
                else
                {
                    path = scriptPattern;
                }

                var policy = new CacheItemPolicy();
                policy.AbsoluteExpiration = DateTime.Now.AddHours(1);
                MemoryCache.Default.Set(scriptPattern, path, policy);
            }

            return path;
        }
    }
}

 

下載JavascriptExtensionsV1.1.cs

 

有任何使用上的問題歡迎告訴我。