您现在的位置是:网站首页> 内容页

Microsoft.AspNet.Web.Optimization.Bundle的完美替换方案

  • 奇迹电游app
  • 2019-05-24
  • 232人已阅读
简介Web应用程序中包含大量的样式(css)和脚本(js)文件,这些文件的引用、管理和发布有很多解决方案。在Asp.NetMVC应用程序中,大家最熟悉的解决方案应属Microsoft.A

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集合即可,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/core/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 > ... </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 && bundle.HasInputFiles) { var paths = new List<string>(); foreach (var inputFile in bundle.inputFiles) { if (File.Exists(inputFile)) { paths.Add(string.Format(format, $"{inputFile}?r={random}")); } else if (Directory.Exists(inputFile)) { var files = Directory.GetFiles(inputFile); foreach (var file in files) { var filePath = file.Replace("\", "/"); paths.Add(string.Format(format, $"{filePath}?r={random}")); } } } html = string.Join(Environment.NewLine, paths); } } return html; } class BundleInfo { public string outputFileName { get; set; } public List<string> inputFiles { get; set; } public bool HasInputFiles { get { return inputFiles != null && inputFiles.Count > 0; } } 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); } }}

文章评论

Top