简体   繁体   English

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

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

I am just trying out ASP.NET MVC 4 but I can't figure out how to disable Javascript/CSS minification feature. 我只是尝试ASP.NET MVC 4,但我无法弄清楚如何禁用Javascript / CSS缩小功能。 Especially for development environment this will help greatly on debugging. 特别是对于开发环境,这将有助于调试。 I would imagine it would be a switch in web.config but since ASP.NET MVC 4 is still in beta stage at the moment there's really not much information out there. 我想这将是web.config中的一个开关,但由于ASP.NET MVC 4目前仍处于测试阶段,因此实际上没有太多信息。 Would appreciate if someone can help or point to the right blog posts etc. 如果有人可以帮助或指向正确的博客文章等,将不胜感激。

In Global.asax.cs 在Global.asax.cs中

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

Another option would be to create an HTML Helper that you could use to build the script and link tags. 另一种选择是创建一个HTML Helper,您可以使用它来构建脚本和链接标记。 Here is what I have implemented for the Javascript, which can also be done for the CSS: 这是我为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());
        }
    }

Now all that you have to do is call it in your view: 现在您需要做的就是在您的视图中调用它:

<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>

And it will render the scripts as separate references, or use the new bundling/minification feature depending on what the debug setting is in your web.config . 它会将脚本呈现为单独的引用,或者使用新的捆绑/缩小功能,具体取决于web.config中的调试设置。 I used some of the code from http://codecutout.com/resource-minify-bundling as a reference when creating my helper if you wanted to see some more examples. 如果您想查看更多示例,我在创建助手时使用了http://codecutout.com/resource-minify-bundling中的一些代码作为参考。 Their helper is written a little better, throwing exceptions when invalid arguments are supplied, etc.... I just haven't gotten around to cleaning mine up yet. 他们的助手写得好一点,在提供无效参数时抛出异常等等......我还没有去清理我的。

You could register your own bundles in the Global.asax and use the NoTransform class if you do not want the content to be minified. 您可以在Global.asax中注册自己的包,如果不希望缩小内容,可以使用NoTransform类。

I personally don't want my script to be transformed at all. 我个人不希望我的剧本完全改变。 I just create two script directories. 我只是创建了两个脚本目录。 One with the debug script versions and one with the originally downloaded minified versions. 一个是调试脚本版本,一个是最初下载的缩小版本。

The MVC 4 out of the box minifier (JsMinify) breaks jQuery 1.7.1 for Opera, so I do not want to use that one. MVC 4开箱即用的minifier(JsMinify)打破了jQuery 1.7.1 for Opera,所以我不想使用那个。 I just put the following lines in my Global.asax : Application_Start() method: 我只是将以下几行放在我的Global.asaxApplication_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);

With that in place I can simply add either one of two lines in my _layouts.cshtml : 有了这个,我可以在我的_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>

Of course we could get a little more funky with this in place. 当然,我们可以通过这种方式获得更多时髦。 We could generate just one bundle and depending on the built type select what files to include. 我们只能生成一个捆绑包,并根据构建的类型选择要包含的文件。

On newer versions of ASP.NET MVC just add 在较新版本的ASP.NET MVC上添加

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

right after 之后

BundleConfig.RegisterBundles(...);

After the call to EnableDefaultBundles() in Global.asax, you can do this ... 在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();
            }
        }

Not pretty (modifying state set by the system), but it's a lot less code than all the other suggestions, still lets you use the standard bundling behavior and it doesn't involve any changes to your views. 不漂亮(修改系统设置的状态),但是代码比所有其他建议少得多,仍然允许您使用标准捆绑行为,并且不会对您的视图进行任何更改。

you can turn it off from config: 你可以从配置中关闭它:

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

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

Rather than replace instances of JsMinify and CssMinify, one can instead use interfaces. 可以改为使用接口,而不是替换JsMinify和CssMinify的实例。 This option was not available in earlier releases because the second constructor parameter was a type rather than an interface. 此选项在早期版本中不可用,因为第二个构造函数参数是类型而不是接口。

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

Perhaps also worth noting, for scripts that are shipped with minified and non-minified versions eg jQuery, one can use a helper method to optionally strip out the ".min" for DEBUG builds to facilitate debugging: 也许值得注意的是,对于带有缩小和非缩小版本(例如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"));

I think it would be right, if such feature will be available "out of the box". 我认为这是正确的,如果这种功能可以“开箱即用”。

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

Give it your "voices". 给它你的“声音”。

Another alternative (tested with v1.1.0.0 and MVC5): 另一种选择(使用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
    }
}

Try a new extension for System.Web.Optimization - Bundle Transformer . 尝试System.Web.Optimization的新扩展 - Bundle Transformer In Bundle Transformer implemented a number of opportunities to simplify debugging (see documentation ). 在Bundle Transformer中实现了许多简化调试的机会(参见文档 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM