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);
}
}
}

Microsoft.AspNet.Web.Optimization.Bundle的完美替换方案的更多相关文章

  1. asp.net webform 中使用Microsoft ASP.NET Web Optimization压缩js及css

    使用静态资源压缩可以合并静态资源文件减少客户端请求数量,压缩文件大小,减少网络流量的损耗. 注:只有通过web.config关闭调试功能,压缩才会生效 <system.web> <c ...

  2. 空MVC项目找不到System.Web.Optimization的处理办法

    install-package Microsoft.AspNet.Web.Optimization Create the bundle in Global.asax Application_Start ...

  3. asp.net mvc4 System.Web.Optimization找不到引用

    在MVC4的开发中,如果创建的项目为空MVC项目,那么在App_Start目录下没有BundleConfig.cs项的内容,在手动添加时在整个库中都找不到:System.Web.Optimizatio ...

  4. System.Web.Optimization找不到引用

    在程序包管理控制程序中录入:Install-Package Microsoft.AspNet.Web.Optimization,安装即可.

  5. vs2012找不到system web optimization命名空间

    今天新装了vs2012,安装完成后,创建了一个mvc4应用程序,创建生成出现了几个错误.通过错误我们的解决方案就是去找引用不到的路径,如何在vs2012中实现呢? 在工具栏中找工具--库程序包管理器- ...

  6. .net mvc System.Web.Optimization 、System.Data.Entity.Infrastructure找不到

    在MVC4的开发中,如果在App_Start目录下BundleConfig.cs类没有找不到引用System.Web.Optimization,可以使用程序包管理控制台进行安装到使用的项目 打开 工具 ...

  7. 安装升级System.Web.Optimization.dll

    今天在使用backload时,VS提示solution所引用的System.Web.Optimization.dll 版本低,编译不过,于是便删掉,从新添加引用,悲剧的是在添加引用窗口中没找到,在Nu ...

  8. System.Web.Optimization找不到引用怎么办?

    Install-Package Microsoft.AspNet.Web.Optimization

  9. System.Web.Optimization 合并压缩技术的使用

    捆绑和压缩原理是:将多个css文件动态合并和压缩为一个css文件.多个js文件动态合并和压缩为一个js文件,如此达到减少浏览器对服务器资源文件的请求数量.缩小资源文件的尺寸来提高页面反应速度的目的.A ...

随机推荐

  1. js导航栏单击事件背景颜色变换

    <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...

  2. 一对一关联模型,HAS_ONE

    class UserModel extends RelationModel{ protected $_link = array( 'Profile'=> HAS_ONE, //就这一行就行了 ) ...

  3. SVG笔记

    SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式.SVG是W3C("World Wide Web C ...

  4. rpm和yum模拟安装

    在更新安装包之前,我们可能会想做一个测试运行,换句话说,模拟而不是实际安装更新的包,以确定在安装之前是否有任何需要处理的问题. 以测试更新openssh2为例: yum update openssh2 ...

  5. SQL SERVER-时间戳(timestamp)与时间格式(datetime)互相转换

    SQL里面有个DATEADD的函数.时间戳就是一个从1970-01-01 08:00:00到时间的相隔的秒数.所以只要把这个时间戳加上1970-01-01 08:00:00这个时间就可以得到你想要的时 ...

  6. git提交到一半关闭时

    一:出现问题 最近写东西,在提交代码时,突然出现一大推文件... 忘记加.gitignore文件了,导致所有的安装依赖也都上传了.所以,点击了关闭按钮,当下一次提交时,出现了错误. Another g ...

  7. spring boot集成aop实现日志记录

    1.pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  8. mysql----------mysql的一些常用命令

    1.查询一张表中某个字段重复值的记录 select id,cert_number from (select id,cert_number,count(*)as n from 表明 group by c ...

  9. redis----------linux和mac如何安装redis和启动,关闭

    1.打开官网https://redis.io/download.官网有安装命令 2.以下是我的执行过程截图 执行完官网给的命令以后,再执行  make PREFIX=/usr/local/redis ...

  10. SQL update select

    SQL update select语句 最常用的update语法是: UPDATE TABLE_NAME SET column_name1 = VALUE WHRER column_name2 = V ...