Microsoft.AspNet.Web.Optimization.Bundle的完美替换方案
程序员文章站
2022-04-18 10:45:36
Web应用程序中包含大量的样式(css)和脚本(js)文件,这些文件的引用、管理和发布有很多解决方案。在Asp.Net MVC应用程序中,大家最熟悉的解决方案应属Microsoft.AspNet.Web.Optimization这个package。这个package的使用也挺方便,对我来说,它依赖太 ......
Web应用程序中包含大量的样式(css)和脚本(js)文件,这些文件的引用、管理和发布有很多解决方案。在Asp.Net MVC应用程序中,大家最熟悉的解决方案应属Microsoft.AspNet.Web.Optimization这个package。这个package的使用也挺方便,对我来说,它依赖太多package,这点不合我胃口,我是比较崇尚精简的那种。接下来介绍这个package的使用及如何将它完美的替换。
1. Microsoft.AspNet.Web.Optimization的Bundle使用
将要合并的文件添加到BundleTable.Bundles集合中即可,样式文件使用StyleBundle类,脚本文件使用ScriptBundle类。示例如下:
public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { var style = new StyleBundle("~/Content/login") .Include("~/Content/common.css", "~/Content/login.css"); bundles.Add(style); var script = new ScriptBundle("~/Scripts/login") .Include("~/Scripts/common.js", "~/Scripts/login.js"); bundles.Add(style); } }
View页面使用Styles和Scripts两个类来呈现。示例如下:
@Styles.Render("~/Content/login") @Scripts.Render("~/Scripts/login")
这里只简单介绍一下Bundle的使用。个人觉得主要有如下问题:
- 依赖过多的package,有WebGrease、Antlr、Newtonsoft.Json;
- 不同文件夹的样式文件不能同时输出一个min文件,若包在一起时,有些样式文件引用的图片无法显示,这个问题我没想去解决,有了上面那一条,也不想去解决它。
2. 完美的替换方案
为了完美替换Microsoft.AspNet.Web.Optimization的Bundle,我采用了Bundler & Minifier这个VS的扩展,它可以方便的配置和生成样式及脚本的min文件。这个扩展只能生成min文件,而没有Bundle那样可以根据开发环境和生产环境来输出对应的源文件和min文件,不过这个问题很好解决,下面来介绍如何实现。
-
安装Bundler & Minifier扩展及配置
在VS中点击“工具-扩展和更新-联机”,再输入Bundler搜索,下载,重启VS完成安装。 -
Bundle的配置
它的配置很简单,配一个outputFileName和inputFiles集合即可。打开bundleconfig.json文件,配置示例如下:
[ { "outputFileName": "static/modules/login/index.min.css", "inputFiles": [ "static/modules/login/index.css" ] }, { "outputFileName": "static/modules/login/index.min.js", "inputFiles": [ "static/libs/jquery.min.js", "static/libs/jquery.md5.js", "static/modules/common.js", "static/modules/login/index.js" ] } ]
-
解决开发环境和生产环境输出特性
我们知道Web.config文件有如下节点,可以设置当前程序的环境,可以通过HttpContextBase类的IsDebuggingEnabled属性来获取。
<configuration> <system.web> <compilation debug="true" /> </system.web> </configuration>
根据这个节点,我们来实现不同环境下样式和脚本文件的输出,即开发时输出源文件,生产环境下输出min文件。我们添加HtmlHelper类的扩展方法,一个是MinStyle输出样式,一个是MinScript输出脚本。View页面使用如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> @Html.MinStyle("static/modules/login/index.min.css") </head> <body> <div class="login"> ... </div> @Html.MinScript("static/modules/login/index.min.js") </body> </html>
下面是这两个扩展方法的具体实现:
public static class HtmlExtension { public static IHtmlString MinStyle(this HtmlHelper helper, string path) { var format = "<link rel=\"stylesheet\" href=\"{0}\">"; var html = GetHtmlString(helper, format, path); return new HtmlString(html); } public static IHtmlString MinScript(this HtmlHelper helper, string path) { var format = "<script src=\"{0}\"></script>"; var html = GetHtmlString(helper, format, path); return new HtmlString(html); } private static string GetHtmlString(HtmlHelper helper, string format, string path) { var random = DateTime.Now.ToString("yyMMddss"); var html = string.Format(format, path + "?r=" + random); var httpContext = helper.ViewContext.RequestContext.HttpContext; if (httpContext.IsDebuggingEnabled) { var bundle = BundleInfo.GetBundle(httpContext, path); if (bundle != null) { var paths = bundle.inputFiles.Select(f => string.Format(format, f + "?r=" + random)); html = string.Join(Environment.NewLine, paths); } } return html; } class BundleInfo { public string outputFileName { get; set; } public List<string> inputFiles { get; set; } public static BundleInfo GetBundle(HttpContextBase httpContext, string outputFile) { var jsonFile = httpContext.Server.MapPath("~/bundleconfig.json"); if (!File.Exists(jsonFile)) return null; var json = File.ReadAllText(jsonFile); if (string.IsNullOrWhiteSpace(json)) return null; var bundles = json.FromJson<List<BundleInfo>>(); if (bundles == null || bundles.Count == 0) return null; return bundles.FirstOrDefault(b => b.outputFileName == outputFile); } } }
下一篇: 跳槽之后面试25余家公司的总结
推荐阅读