如何在ASP.NET MVC 4 Beta中禁用Javascript/CSS缩小

How to disable Javascript/CSS minification in ASP.NET MVC 4 Beta

本文关键字:Javascript 缩小 CSS Beta ASP NET MVC      更新时间:2023-09-26

我只是在尝试ASP.NET MVC 4,但我不知道如何禁用Javascript/CSS缩小功能。特别是对于开发环境,这将大大有助于调试。我想这将是web.config中的一个切换,但由于ASP.NET MVC 4目前仍处于测试阶段,所以实际上没有太多信息。如果有人能提供帮助或指向正确的博客文章等,我将不胜感激。

在Global.asax.cs 中

#if DEBUG
        foreach (var bundle in BundleTable.Bundles)
        {
            bundle.Transform = new NoTransform();
        }
#endif

另一个选项是创建一个HTML Helper,用于构建脚本和链接标记。以下是我为Javascript实现的内容,也可以为CSS:实现

public static class BundleHelper
    {
        public static MvcHtmlString JsBundle(this HtmlHelper helper, string bundlePath)
        {
            var jsTag = new TagBuilder("script");
            jsTag.MergeAttribute("type", "text/javascript");
            return ReferenceBundle(helper, bundlePath, jsTag);
        }
        public static MvcHtmlString ReferenceBundle(this HtmlHelper helper, string bundlePath, TagBuilder baseTag)
        {
            var httpContext = helper.ViewContext.HttpContext;
            var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
            Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath);
            var htmlString = new StringBuilder();
            if (bundle != null)
            {
                var bundleContext = new BundleContext(helper.ViewContext.HttpContext, BundleTable.Bundles, urlHelper.Content(bundlePath));
                if (!httpContext.IsDebuggingEnabled)
                {
                    baseTag.MergeAttribute("href", System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(bundlePath));
                    return new MvcHtmlString(baseTag.ToString());
                }
                foreach (var file in bundle.EnumerateFiles(bundleContext))
                {
                    var basePath = httpContext.Server.MapPath("~/");
                    if (file.FullName.StartsWith(basePath))
                    {
                        var relPath = urlHelper.Content("~/" + file.FullName.Substring(basePath.Length));
                        baseTag.MergeAttribute("href", relPath, true);
                        htmlString.AppendLine(baseTag.ToString());
                    }
                }
            }
            return new MvcHtmlString(htmlString.ToString());
        }
    }

现在你所要做的就是在你的视野中称之为:

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - My ASP.NET MVC Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <link href="~/Content/css" rel="stylesheet" type="text/css" />
    <link href="~/Content/themes/base/css" rel="stylesheet" type="text/css" />
    @Html.JsBundle("~/scripts/js")
    <meta name="viewport" content="width=device-width" />
</head>

它会将脚本呈现为单独的引用,或者根据web.config中的调试设置使用新的绑定/缩小功能http://codecutout.com/resource-minify-bundling如果你想看更多的例子,可以在创建我的助手时作为参考。他们的助手写得稍微好一点,在提供无效参数时抛出异常,等等……我只是还没有时间清理我的助手。

如果不想缩小内容,您可以在Global.asax中注册自己的捆绑包,并使用NoTransform类。

我个人根本不希望我的剧本被修改。我只创建了两个脚本目录。一个是调试脚本版本,另一个是最初下载的缩小版本。

MVC 4开箱即用的迷你程序(JsMinify)破坏了Opera的jQuery 1.7.1,所以我不想使用它。我只是在我的Global.asax:Application_Start()方法中放了以下几行:

Bundle debugScripts = new Bundle("~/DebugScripts", 
    new NoTransform("text/javascript"));
debugScripts.AddDirectory("~/Scripts/Debug", "*.js");
BundleTable.Bundles.Add(debugScripts);
Bundle productionScripts = new Bundle("~/ProductionScripts", 
    new NoTransform("text/javascript"));
productionScripts.AddDirectory("~/Scripts/Minified", "*.js");
BundleTable.Bundles.Add(productionScripts);

有了它,我可以简单地在_layouts.cshtml:中添加两行中的任意一行

<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/DebugScripts")" type="text/javascript"></script>
<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/ProductionScripts")" type="text/javascript"></script>

当然,有了这个,我们可以变得更时髦一些。我们可以只生成一个捆绑包,并根据构建的类型选择要包含的文件。

在Global.asax中调用EnableDefaultBundles()之后,您可以执行以下操作。。。

        if ( ... running in development environment ...)
        {
            var registeredBundles = BundleTable.Bundles.GetRegisteredBundles();
            foreach (var bundle in registeredBundles)
            {
                if (bundle.Transform is System.Web.Optimization.JsMinify)
                    bundle.Transform = new NoTransform();
            }
        }

不漂亮(修改系统设置的状态),但它比所有其他建议都少了很多代码,仍然允许您使用标准的绑定行为,并且不涉及对视图的任何更改。

在较新版本的ASP.NET MVC上,只需添加

#if DEBUG
            foreach (var bundle in BundleTable.Bundles)
            {
                bundle.Transforms.Clear();
            }
#endif

之后

BundleConfig.RegisterBundles(...);

您可以从config:中将其关闭

<system.web>
    <compilation debug="true" />
    <!-- Lines removed for clarity. -->
</system.web>

http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

如果这样的功能"开箱即用",我认为这是正确的。

我在UserVoice.com上发布了一条反馈:http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/2702000-improve-system-web-optimization-bundle

给它你的"声音"。

与其替换JsMinify和CssMinify的实例,不如使用接口此选项在早期版本中不可用,因为第二个构造函数参数是类型而不是接口

IBundleTransform jsTransform;
IBundleTransform cssTransform;
#if DEBUG
    jsTransform = new NoTransform("text/javascript");
    cssTransform = new NoTransform("text/css");
#else
    jsTransform = new JsMinify();
    cssTransform = new CssMinify();
#endif
Bundle jsBundle = new Bundle("~/JsB", jsTransform);
Bundle cssBundle = new Bundle("~/CssB", cssTransform);

也许还值得注意的是,对于带有缩小版和非缩小版的脚本,例如jQuery,可以使用助手方法选择性地去掉DEBUG构建的".min",以便于调试:

private string Min(string scriptNameIncludingMin)
{
#if DEBUG
    return scriptNameIncludingMin.Replace(".min", ""); // Remove .min from debug builds
#else
    return scriptNameIncludingMin;
#endif
}
// ...
jsBundle.AddFile(Min("~/Scripts/jquery-1.7.2.min.js"));

尝试对System.Web.Optimization-Bundle Transformer进行新的扩展。In-Bundle Transformer实现了许多简化调试的机会(请参阅文档)。

另一种替代方案(使用v1.0.0和MVC5测试):

public class BundleConfig
{
    public static void Register()
    {
        ScriptBundle jsBundle = new ScriptBundle("~/Scripts/myscript.min.js");
        jsBundle.Include("~/Scripts/myscript.js");
        DisableInDebugMode(jsBundle);
        BundleTable.Bundles.Add(jsBundle);
    }
    private static void DisableInDebugMode(ScriptBundle jsBundle)
    {
    #if DEBUG
        // Don't minify in debug mode
        jsBundle.Transforms.Clear();
    #endif
    }
}