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

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 4 Beta 中禁用 Javascript/CSS 缩小【英文标题】:How to disable Javascript/CSS minification in ASP.NET MVC 4 Beta 【发布时间】:2012-03-11 11:57:50 【问题描述】:

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

【问题讨论】:

只有我,或者这不是配置设置是荒谬的? @Jeff:Ruby on Rails 有其自身的局限性,每个平台也一样。 【参考方案1】:

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

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

紧接着

BundleConfig.RegisterBundles(...);

【讨论】:

【参考方案2】:

另一种选择(使用 v1.1.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
    

【讨论】:

【参考方案3】:

您可以从配置中将其关闭:

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

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

【讨论】:

【参考方案4】:

与其替换 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"));

【讨论】:

这是否会停止 js 连接以及缩小?调试单个巨大的 js 文件也很烦人。【参考方案5】:

尝试 System.Web.Optimization 的新扩展 - Bundle Transformer。在 Bundle Transformer 中实现了许多简化调试的机会(请参阅documentation)。

【讨论】:

【参考方案6】:

我认为,如果此类功能“开箱即用”可用,那将是正确的。

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

给它你的“声音”。

【讨论】:

【参考方案7】:

在 Global.asax.cs 中

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

【讨论】:

这在最新版本中已经改变了,详情请看这个答案:***.com/a/11270224 @Michael:是的,但答案是正确的 for beta 正如 OP 要求的那样 :-) 我还有一个 MVC 4 beta 网站尚未升级和高兴我找到了这个答案:-)【参考方案8】:

如果您不想缩小内容,您可以在 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>

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

【讨论】:

【参考方案9】:

在 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();
            
        

不漂亮(修改系统设置的状态),但它的代码比所有其他建议要少得多,仍然可以让您使用标准的捆绑行为,并且不涉及对您的视图进行任何更改。

【讨论】:

【参考方案10】:

另一种选择是创建一个 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 中的一些代码作为参考。他们的助手写得更好一些,当提供无效参数时抛出异常等等......我只是还没来得及清理我的。

【讨论】:

以上是关于如何在 ASP.NET MVC 4 Beta 中禁用 Javascript/CSS 缩小的主要内容,如果未能解决你的问题,请参考以下文章

跟我一起学习ASP.NET 4.5 MVC4.0

iis6 上的 Asp.net mvc 4:“找不到页面”

ASP.NET MVC Beta 路由、控制器操作、参数和 ActionsLinks...把它们放在一起

如何在 ASP.NET MVC 中调试死机白屏

ASP.NET Mvc5+EF7

ASP.NET MVC 4(测试版)中 HTML-5 data-* 属性的使用是不是中断?