【问题标题】:ASP.NET Bundles how to disable minificationASP.NET Bundles 如何禁用缩小
【发布时间】:2012-08-10 07:10:07
【问题描述】:

我的 web.config(s) 中都有 debug="true",我只是不希望我的包被缩小,但我似乎没有做任何事情来禁用它。我试过enableoptimisations=false,这是我的代码:

//Javascript
bundles.Add(new ScriptBundle("~/bundles/MainJS")
            .Include("~/Scripts/regular/lib/mvc/jquery.validate.unobtrusive.js*")
            .Include("~/Scripts/regular/lib/mvc/jquery.validate*")
            .Include("~/Scripts/regular/lib/bootstrap.js")
            .IncludeDirectory("~/Scripts/regular/modules", "*.js", true)
            .IncludeDirectory("~/Scripts/regular/pages", "*.js", true)
            .IncludeDirectory("~/Scripts/regular/misc", "*.js", true));

//CSS
bundles.Add(new StyleBundle("~/bundles/MainCSS")
            .Include("~/Content/css/regular/lib/bootstrap.css*")
            .IncludeDirectory("~/Content/css/regular/modules", "*.css", true)
            .IncludeDirectory("~/Content/css/regular/pages", "*.css", true))

【问题讨论】:

  • @RickAnd-MSFT 该请求是如何在禁用缩小的同时启用捆绑。使用 web.config debug = true/false 或 EnableOptimizations 只能同时打开或关闭。 Martin Devillers 的回答允许在禁用缩小时启用捆绑
  • 也为我....对于捆绑中的文件“x.js”,请确保文件夹中没有“x.min.js”文件,否则尽管您已删除缩小转换 .. 捆绑将提供“预”缩小文件,例如如果你有 'angular.js' 然后删除 'angular.min.js' ;-)

标签: asp.net asp.net-mvc asp.net-mvc-4 bundle asp.net-optimization


【解决方案1】:

条件编译指令是你的朋友:

#if DEBUG
            var jsBundle = new Bundle("~/Scripts/js");
#else
            var jsBundle = new ScriptBundle("~/Scripts/js");
#endif

【讨论】:

  • 实际上我认为他已经搞定了——为了关闭缩小,按照 Hao 使用 Bundle,否则使用捆绑和缩小的 ScriptBundle,不是吗?
  • 当你想通过它的包引用 URI 来引用包时,这是一个很好的解决方案,例如通过 RequireJS 加载而不使用 RequireJS 自己的捆绑/缩小系统。
  • 我看到像 Adam 这样的东西,我将 ScriptBundle 理解为增强的 Bundle,所以既然您想添加基本参考(没有特定的后期操作),在我看来,Bundle 是禁用缩小的好方法在特定的捆绑包上。
  • @RickAnd-MSFT 我认为你误解了这段代码的目的,它允许在调试模式下捆绑 + 不缩小和在发布模式下捆绑 + 缩小。使用 web.config debug = true/false 或 EnableOptimizations 只能同时打开或关闭。我阅读了您的评论并驳回了这个 Martin 的解决方案,却发现它实际上是一种非常好的捆绑方式,无需缩小
  • -1 这个“解决方案”充其量只是权宜之计。实际上,即使它有效,它也会导致非常难以维护的代码。但这还不是最糟糕的事情。使用“Bundle”会导致服务器移交资产,并将 mime-type 设置为“text/html”而不是“text/javascript”。如果您将此方法应用于捆绑 css 文件,则在调试模式下您正在玩火。别。只是不要。请参阅我的答案,了解更健康的方法,该方法在生产构建中有效。
【解决方案2】:

如果您在 web.config 中有 debug="true" 并且使用 Scripts/Styles.Render 来引用页面中的捆绑包,则应该关闭捆绑和缩小。 BundleTable.EnableOptimizations = false 也将始终关闭捆绑和缩小(无论调试真/假标志如何)。

您可能没有使用Scripts/Styles.Render 助手吗?如果您通过BundleTable.Bundles.ResolveBundleUrl() 直接呈现对捆绑包的引用,您将始终获得缩小/捆绑的内容。

【讨论】:

  • 从这个答案中,我不确定如何关闭 just 缩小并保留捆绑 - 这可能吗?
  • 要做到这一点,最简单的方法是将脚本/样式包更改为默认没有设置转换的普通包,这将关闭缩小但仍然包。请注意,您仍然必须将 EnableOptimizations 设置为 true 才能进行捆绑。
  • 也为我....对于捆绑中的文件“x.js”,请确保文件夹中没有“x.min.js”文件,否则尽管您已删除缩小转换..捆绑将提供“预”缩小文件,例如如果你有 'angular.js' 然后删除 'angular.min.js' ;-)
  • @stooboo 这是为我解决的问题,但您不需要删除任何内容。只需包含非最小文件。
  • EnableOptimizations = false - 这段代码属于哪里?
【解决方案3】:

要禁用捆绑和缩小,只需将其放入您的 .aspx 文件 (即使 web.config 中的 debug=true 也会禁用优化)

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c#.net

System.Web.Optimization.BundleTable.EnableOptimizations = false;

如果您将EnableOptimizations = true 放入,即使debug=trueweb.config

中,它也会捆绑并缩小

【讨论】:

  • 这是为我解决问题的唯一方法。我有debug="true" 和正确的Script.Render,但它仍然无法正常工作。另请注意,这不会提供任何 .min.js 文件,因此请确保包含未缩小的依赖代码副本。
  • @TCC:我认为 vb.net 语法应该有大写字母 False 是不是错了?
  • @jeremysawesome 哦,是的,我认为这是正确的,好点 :-) 我不是 VB 程序员,所以我什至没有注意到...
  • 第一行应该是“...即使 debug=false” 不?
  • vb.Net不关心大小写,False=false,比如.tostring() = .toString()
【解决方案4】:

您可以通过清除转换来关闭捆绑包中的缩小功能。

var scriptBundle = new ScriptBundle("~/bundles/scriptBundle");
...
scriptBundle.Transforms.Clear();

当我想将我的所有脚本捆绑在一个文件中但在调试阶段需要可读性时,我个人发现这很有用。

【讨论】:

  • -1 这里是龙:撕掉 JsMinifier/CssMinifier 也撕掉了将 mime-type 设置为“text/css”或“text/javascript”的内部机制。这不会在调试/发布模式下造成问题,但会在已发布的构建(也称为实时部署)的上下文中对 css-bundle 造成严重破坏:Chrome 和 firefox 拒绝加载所述 css-bundle,并声明它们的 mime-types 设置为“文本/html”而不是“文本/css”。使用 js-bundles 可以以某种方式进行锻炼,但将 js-bundle 作为“text/html”(
【解决方案5】:

我尝试了很多这些建议,但注意到似乎有效。我浪费了好几个小时才发现这是我的错误:

@Scripts.Render("/bundles/foundation")

无论我尝试什么,它总是让我缩小和捆绑 javascript。相反,我应该使用这个:

@Scripts.Render("~/bundles/foundation")

额外的“~”做到了。我什至只在一个实例中再次删除了它,看看是否真的如此。那是……希望我能节省至少一个人浪费在这上面的时间。

【讨论】:

  • 哇,过去 3 个小时我都快疯了……
【解决方案6】:

结合几个答案,这在 ASP.NET MVC 4 中对我有用。

        bundles.Add(new ScriptBundle("~/Scripts/Common/js")
            .Include("~/Scripts/jquery-1.8.3.js")
            .Include("~/Scripts/zizhujy.com.js")
            .Include("~/Scripts/Globalize.js")
            .Include("~/Scripts/common.js")
            .Include("~/Scripts/requireLite/requireLite.js"));

        bundles.Add(new StyleBundle("~/Content/appLayoutStyles")
            .Include("~/Content/AppLayout.css"));

        bundles.Add(new StyleBundle("~/Content/css/App/FunGrapherStyles")
            .Include("~/Content/css/Apps/FunGrapher.css")
            .Include("~/Content/css/tables.css"));

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

【讨论】:

    【解决方案7】:

    还有一些简单的方法可以手动控制缩小(和其他功能)。它是新的 CssMinify() 转换器,使用如下:

    // this is in case when BundleTable.EnableOptimizations = false;
    var myBundle = new StyleBundle("~/Content/themes/base/css")
        .Include("~/Content/themes/base/jquery.ui.core.css" /* , ... and so on */);
    myBundle.Transforms.Add(new CssMinify());
    bundles.Add(myBundle);
    
    // or you can remove that transformer in opposite situation
    myBundle.Transforms.Clear();
    

    当您希望某些捆绑包的特殊部分仅被缩小时,这很方便。比方说,您正在使用一些标准 (jQuery) 样式,这些样式在您的脚下(接受大量过多的浏览器请求),但您希望保持自己的样式表不缩小。 (同样 - 使用 javascript)。

    【讨论】:

      【解决方案8】:

      我结合了其他人在这个问题中给出的一些答案,提出了另一种替代解决方案。

      目标:始终捆绑文件,在出现<compilation debug="true" ... /> 的情况下禁用 JS 和 CSS 缩小,并始终对 CSS 捆绑包应用自定义转换。

      我的解决方案

      1) 在 web.config 中: <compilation debug="true" ... />

      2) 在 Global.asax Application_Start() 方法中:

       protected void Application_Start() {
           ...
           BundleTable.EnableOptimizations = true; // Force bundling to occur
      
           // If the compilation node in web.config indicates debugging mode is enabled
           // then clear all transforms. I.e. disable Js and CSS minification.
           if (HttpContext.Current.IsDebuggingEnabled) {
               BundleTable.Bundles.ToList().ForEach(b => b.Transforms.Clear());
           }
      
            // Add a custom CSS bundle transformer. In my case the transformer replaces a
            // token in the CSS file with an AppConfig value representing the website URL
            // in the current environment. E.g. www.mydevwebsite in Dev and
            // www.myprodwebsite.com in Production.
            BundleTable.Bundles.ToList()
                .FindAll(x => x.GetType() == typeof(StyleBundle))
                .ForEach(b => b.Transforms.Add(new MyStyleBundleTransformer()));
           ...
      }
      

      【讨论】:

        【解决方案9】:

        如果您将以下属性设置为 false,那么它将禁用捆绑和缩小。

        Global.asax.cs 文件中,添加如下所述的行

        protected void Application_Start()
        {
            System.Web.Optimization.BundleTable.EnableOptimizations = false;
        }
        

        【讨论】:

        • 我只是不明白为什么我关闭了这个功能后我的less文件会转换为css?当我启用优化时,捆绑更少的文件不再起作用。
        【解决方案10】:

        在您的项目中搜索 EnableOptimizations 关键字

        所以如果你发现

        BundleTable.EnableOptimizations = true;
        

        false

        这确实会禁用缩小, 它还完全禁用捆绑

        【讨论】:

        • 这确实禁用了缩小,但它也完全禁用了捆绑,我认为至少应该注意这一点。
        【解决方案11】:

        以下是针对每个捆绑包禁用缩小的方法:

        bundles.Add(new StyleBundleRaw("~/Content/foobarcss").Include("/some/path/foobar.css"));
        bundles.Add(new ScriptBundleRaw("~/Bundles/foobarjs").Include("/some/path/foobar.js"));
        

        旁注:用于您的包的路径不得与您发布的构建中的任何实际路径一致,否则将无法正常工作。还要确保避免使用 .js、.css 和/或 '.'和 '_' 包名称中的任何位置。保持名称尽可能简单明了,如上例所示。

        帮助类如下所示。请注意,为了使这些类面向未来,我们通过外科手术删除了 js/css 缩小实例而不是使用 .clear() 并且我们还插入了一个 mime-type-setter 转换,如果没有它,生产构建肯定会遇到麻烦,尤其是在涉及到正确移交 css 捆绑包(firefox 和 chrome 拒绝将 mime-type 设置为“text/html”的 css 捆绑包,这是默认设置):

        internal sealed class StyleBundleRaw : StyleBundle
        {
                private static readonly BundleMimeType CssContentMimeType = new BundleMimeType("text/css");
        
                public StyleBundleRaw(string virtualPath) : this(virtualPath, cdnPath: null)
                {
                }
        
                public StyleBundleRaw(string virtualPath, string cdnPath) : base(virtualPath, cdnPath)
                {
                         Transforms.Add(CssContentMimeType); //0 vital
                         Transforms.Remove(Transforms.FirstOrDefault(x => x is CssMinify)); //0
                }
                //0 the guys at redmond in their infinite wisdom plugged the mimetype "text/css" right into cssminify    upon unwiring the minifier we
                //  need to somehow reenable the cssbundle to specify its mimetype otherwise it will advertise itself as html and wont load
        }
        
        internal sealed class ScriptBundleRaw : ScriptBundle
        {
                private static readonly BundleMimeType JsContentMimeType = new BundleMimeType("text/javascript");
        
                public ScriptBundleRaw(string virtualPath) : this(virtualPath, cdnPath: null)
                {
                }
        
                public ScriptBundleRaw(string virtualPath, string cdnPath) : base(virtualPath, cdnPath)
                {
                         Transforms.Add(JsContentMimeType); //0 vital
                         Transforms.Remove(Transforms.FirstOrDefault(x => x is JsMinify)); //0
                }
                //0 the guys at redmond in their infinite wisdom plugged the mimetype "text/javascript" right into jsminify   upon unwiring the minifier we need
                //  to somehow reenable the jsbundle to specify its mimetype otherwise it will advertise itself as html causing it to be become unloadable by the browsers in published production builds
        }
        
        internal sealed class BundleMimeType : IBundleTransform
        {
                private readonly string _mimeType;
        
                public BundleMimeType(string mimeType) { _mimeType = mimeType; }
        
                public void Process(BundleContext context, BundleResponse response)
                {
                         if (context == null)
                                  throw new ArgumentNullException(nameof(context));
                         if (response == null)
                                  throw new ArgumentNullException(nameof(response));
        
                 response.ContentType = _mimeType;
                }
        }
        

        要使这一切正常工作,您需要安装(通过 nuget):

        WebGrease 1.6.0+ Microsoft.AspNet.Web.Optimization 1.1.3+

        你的 web.config 应该像这样丰富:

        <runtime>
               [...]
               <dependentAssembly>
                <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
                <bindingRedirect oldVersion="1.0.0.0-x.y.z.t" newVersion="x.y.z.t" />
               </dependentAssembly>
               <dependentAssembly>
                      <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-x.y.z.t" newVersion="x.y.z.t" />
               </dependentAssembly>
                [...]
        </runtime>
        
        <!-- setting mimetypes like we do right below is absolutely vital for published builds because for some reason the -->
        <!-- iis servers in production environments somehow dont know how to handle otf eot and other font related files   -->
        <system.webServer>
                [...]
                <staticContent>
              <!-- in case iis already has these mime types -->
              <remove fileExtension=".otf" />
              <remove fileExtension=".eot" />
              <remove fileExtension=".ttf" />
              <remove fileExtension=".woff" />
              <remove fileExtension=".woff2" />
        
              <mimeMap fileExtension=".otf" mimeType="font/otf" />
              <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
              <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
              <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
              <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
              </staticContent>
        
              <!-- also vital otherwise published builds wont work  https://stackoverflow.com/a/13597128/863651  -->
              <modules runAllManagedModulesForAllRequests="true">
                 <remove name="BundleModule" />
                 <add name="BundleModule" type="System.Web.Optimization.BundleModule" />
              </modules>
              [...]
        </system.webServer>
        

        请注意,您可能需要采取额外的步骤才能使您的 css-bundle 在字体等方面工作。但这是另一回事。

        【讨论】:

          【解决方案12】:

          只是为了补充已经给出的答案,如果您还想不缩小/混淆/连接某些文件,同时仍允许对其他文件进行完全捆绑和缩小,最好的选择是使用自定义渲染器,它将读取特定捆绑包的内容并渲染页面中的文件,而不是渲染捆绑包的虚拟路径。我个人需要这样做,因为当我的 CSS 文件被捆绑时,IE 9 是 $*%@ing the bed 即使关闭了缩小功能

          非常感谢this article,它给了我用于创建 CSS 渲染器的代码的起点,该渲染器将为 CSS 渲染文件,但仍然允许系统渲染我的 javascript 文件捆绑/缩小/混淆了。

          创建了静态帮助类:

          using System;
          using System.Text;
          using System.Web;
          using System.Web.Mvc;
          using System.Web.Optimization;
          
          namespace Helpers
          {
            public static class OptionalCssBundler
            {
              const string CssTemplate = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
          
              public static MvcHtmlString ResolveBundleUrl(string bundleUrl, bool bundle)
              {
                return bundle ? BundledFiles(BundleTable.Bundles.ResolveBundleUrl(bundleUrl)) : UnbundledFiles(bundleUrl);
              }
          
              private static MvcHtmlString BundledFiles(string bundleVirtualPath)
              {
                return new MvcHtmlString(string.Format(CssTemplate, bundleVirtualPath));
              }
          
              private static MvcHtmlString UnbundledFiles(string bundleUrl)
              {
                var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);
          
                StringBuilder sb = new StringBuilder();
                var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
          
                foreach (BundleFile file in bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl)))
                {
                  sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath));
                }
          
                return new MvcHtmlString(sb.ToString());
              }
          
              public static MvcHtmlString Render(string bundleUrl, bool bundle)
              {
                return ResolveBundleUrl(bundleUrl, bundle);
              }
            }
          
          }
          

          然后在剃刀布局文件中:

          @OptionalCssBundler.Render("~/Content/css", false)
          

          代替标准:

          @Styles.Render("~/Content/css")
          

          我确信为 javascript 文件创建一个可选的渲染器也几乎不需要更新到这个帮助器。

          【讨论】:

          • 效果很好。如果您希望在文件更新时更改 url,您可以将 CssTemplate 更改为 "&lt;link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" /&gt;" 并将 sb.AppendFormat 行更改为 sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
          • 没错,我们在工作中做了很多类似的事情。我们有一个名为 JSVersion 的公共静态字符串,我们将它放入 Global.asax 类中,该类会提取正在执行的程序集的 maj/min/build/rev。然后我们像这样引用它:
          【解决方案13】:

          如果您使用 LESS/SASS CSS 转换,则可以将选项 useNativeMinification 设置为 false 以禁用缩小(在 web.config 中)。出于我的目的,我只是在需要时在此处更改它,但您可以使用 web.config 转换来始终在发布构建时启用它,或者找到一种在代码中修改它的方法。

          <less useNativeMinification="false" ieCompat="true" strictMath="false"
                strictUnits="false" dumpLineNumbers="None">
          

          提示: 这样做的全部目的是查看您的 CSS,您可以在浏览器检查工具中执行此操作,或者只需打开文件即可。启用捆绑后,每次编译时文件名都会更改,因此我将以下内容放在页面顶部,以便每次更改时都可以在新的浏览器窗口中轻松查看已编译的 CSS。

          @if (Debugger.IsAttached) 
          {
              <a href="@Styles.Url(ViewBag.CSS)" target="css">View CSS</a>
          }
          

          这将是一个动态 URL,类似于 https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


          更新:我创建了一个 web.config 转换,以便在部署/发布构建期间为我将其设置为 true

            <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
              <less xdt:Transform="Replace" useNativeMinification="true" ieCompat="true" strictMath="false" strictUnits="false" dumpLineNumbers="None">
                <jsEngine name="MsieJsEngine" />
              </less>
            </bundleTransformer>
          

          【讨论】:

          • 文件名不会在每次编译时改变。它基于文件内容,因此每当文件更改时都会更改。
          【解决方案14】:

          这可能对将来的某些人有用,因为新框架在通过 VS 设置时会获得默认的 web.configweb.Debug.configweb.Release.config。在web.release.config 你会发现这一行:

          <compilation xdt:Transform="RemoveAttributes(debug)" />
          

          这似乎覆盖了我所做的任何内联更改。我评论了这条线,我们很高兴(就在“发布”版本中看到非缩小代码而言)

          【讨论】:

            猜你喜欢
            • 2012-03-11
            • 2013-12-16
            • 2015-08-12
            • 2017-09-19
            • 2019-11-16
            • 1970-01-01
            相关资源
            最近更新 更多