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. C#进度条简单应用

    进度条表示文件复制的进度: 1.将进度条最大值设置为需要复制的文件总数 2.遍历文件时每复制一个文件之后,进度条+1 ;//文件总数 progressBar1.Value = progressBar1 ...

  2. MySQL中的EXPLAIN

    使用EXPLAIN加上SELECT语句可以获取优化器的查询执行计划 MySQL会在查询上设置一个标记,当执行查询时,这个标记会返回关于在执行计划中每一步的信息,而不是执行它.它会返回一行或多行信息,一 ...

  3. linux pwd命令 显示当前所在路径

    pwd 显示当前所在路径 [root@MongoDB ~]# pwd /root

  4. python tkinter entry

    """小白随笔,大佬勿喷""" '''Entry编辑框 收集数据''' import tkinter as tk import tkinte ...

  5. 微信小程序 加载图片时,先拉长,再恢复正常

    今天在写小程序,发现小程序的图片image如过mode设置为widthFix的话, 加载图片会被先拉伸,后恢复正常 我的处理方法是,给他一个初始的height值,或者就直接 height:auto

  6. LeetCode 15 输入无序、有重复,输出排重版 3-Sum

    V1 粗暴的遍历,时间复杂度O(N³) func threeSumClosest(nums []int, target int) int { min := 0 result := 0 for i := ...

  7. Lintcode: Knight Shortest Path

    Given a knight in a chessboard (a binary matrix with 0 as empty and 1 as barrier) with a source posi ...

  8. program与module

    program,各方面与module都类似,其中声明的变量在program中都可见, 生命周期也是static类型的, program的结束,也是需要等待其中的所有initial块都执行结束. 与mo ...

  9. TypeScript之interface初探

    TypeScript的核心原则之一是对值所具有的结构进行类型检查,在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约. function printLabel(la ...

  10. dom反转

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...