Microsoft.AspNet.Web.Optimization.Bundle的完美替换方案
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(script); } }
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 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 && bundle.HasInputFiles) { var rootPath = httpContext.Server.MapPath("~/"); var paths = new List<string>(); foreach (var inputFile in bundle.inputFiles) { var inputPath = rootPath + inputFile; if (File.Exists(inputPath)) { paths.Add(string.Format(format, $"{inputFile}?r={random}")); } else if (Directory.Exists(inputPath)) { var files = Directory.GetFiles(inputPath); foreach (var file in files) { var filePath = file.Replace(rootPath, "").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); } } }
Known 是基于 Blazor 轻量级、跨平台、低代码、易扩展的插件开发框架。
源码:https://gitee.com/known/Known
源码:https://github.com/known/Known
如果对您有帮助,点击⭐Star⭐关注 ,感谢支持开源!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!