ASP.NET捆绑包如何禁用缩小


185

我都debug="true"在我的web.config(s)中,但我只是不想缩小我的捆绑包,但是我似乎没有做任何事情来禁用它。我试过了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))

2
@ RickAnd-MSFT请求是如何在禁用缩小功能的同时启用捆绑功能。使用web.config debug = true / false或EnableOptimizations只能打开或关闭两者。Martin Devillers的答案允许在禁用
缩小

2
对我来说....对于捆绑包中的文件'x.js',请确保文件夹中没有'x.min.js'文件,否则,尽管您已删除了缩小转换。.捆绑将为“预先”缩小文件,例如,如果您具有“ angular.js”,则删除“ angular.min.js” ;-)
stooboo

Answers:


137

如果您debug="true"web.config中,并且Scripts/Styles.Render用于引用页面中的捆绑软件,则应该同时关闭捆绑和缩小功能。BundleTable.EnableOptimizations = false也会同时关闭捆绑和最小化(与debug true / false标志无关)。

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


12
从这个答案中,我不确定如何关闭缩小功能并保持捆绑状态-这可能吗?
Adam Tuliper-MSFT 2012年

33
为此,最简单的方法是将Script / StyleBundles更改为默认情况下未设置Transform的普通Bundle,这将关闭缩小功能,但仍会捆绑。请注意,您仍然必须将EnableOptimizations设置为true才能进行绑定。
郝公2012年

2
对我来说....对于捆绑包中的文件'x.js',请确保文件夹中没有'x.min.js'文件,否则,尽管您已删除了缩小转换。.捆绑将为“预先”缩小文件,例如,如果您具有“ angular.js”,则删除“ angular.min.js” ;-)
stooboo

1
@stooboo这是为我解决的问题,但您无需删除任何内容。只需包含非min文件即可。
OneHoopyFrood 2014年

2
EnableOptimizations = false-此代码在哪里?
亚历克斯

158

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

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

16
实际上,我认为他已对此钉上了钉子-为了仅关闭缩小功能,请按照Hao使用Bundle,否则请使用捆绑并缩小的ScriptBundle,不是吗?
Adam Tuliper-MSFT 2012年

1
当您想通过捆绑包引用URI来引用捆绑包以进行诸如通过RequireJS加载而不使用RequireJS自己的捆绑/缩小系统之类的事情时,这是一个很好的解决方案。
诺曼H

1
我看到类似Adam的东西,我将ScriptBundle理解为增强的Bundle,因此,由于您想添加基本引用(无特定的后期操作),因此Bundle在我看来是禁用特定Bundle上的缩小的一种好方法。
Charles HETIER 2013年

6
@ RickAnd-MSFT我认为您误解了此代码的目的,该代码允许在调试模式下捆绑+最小化,而在发布模式下捆绑+最小化。使用web.config debug = true / false或EnableOptimizations只能打开或关闭两者。我阅读了您的评论,并驳回了Martin的解决方案,但发现它实际上是一种非常有效的捆绑方式,而且没有缩小
家伙

-1这个“解决方案”充其量是一个权宜之计。实际上,即使它起作用,也会导致非常难以维护的代码。但这不是最糟糕的事情。使用“捆绑包”会导致服务器将mime-type设置为“ text / html”而不是“ text / javascript”来移交资产。如果您将这种方法用于捆绑css文件,则在调试模式下会遇到麻烦。别。只是不要。请参阅我的答案,以获得在生产环境中有效的更健康的方法。
XDS

89

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

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c#.net

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

如果放了EnableOptimizations = true,即使debug=trueweb.config中,它也会捆绑并缩小


2
这是唯一为我解决问题的方法。我拥有debug="true"并拥有权利,Script.Render但仍然无法正常工作。另请注意,这将不会存储任何.min.js文件,因此请确保包含未缩小的依赖关系代码副本。
OneHoopyFrood

2
@TCC:我认为vb.net语法应该有大写字母是错误的False吗?
jeremysawesome

@jeremysawesome哦,是的,我认为这是正确的,好点子:-)我不是VB程序员,所以我什至没有注意到……
TCC 2015年

1
第一行应该是“ ...即使debug = false也不行”?
UnionP

2
vb.Net不在乎大小写,False = false,例如.tostring()= .toString()
manuel

67

您只需清除转换即可关闭包中的缩小。

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

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


-1这是一条龙:剥开JsMinifier / CssMinifier还会剥夺将mime-type设置为“ text / css”或“ text / javascript”的内部机制。这不会在调试/发布模式下引起问题,但是会在已发布的版本(也称为实时部署)的上下文中给css-bundles造成严重破坏:Chrome和firefox拒绝加载所述css-bundle,表明它们的mime类型设置为“ text / html”而不是“ text / css”。使用js-bundle可以进行某种方式的锻炼,但是最好将js-bundle移交为“ text / html”(<-认真?)。请参阅我的答案以获取正确的方法。
XDS

27

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

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

无论我尝试什么,它总是让我缩小并捆绑JavaScript。相反,我应该使用以下代码:

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

多余的“〜”做到了。我什至只在一次实例中再次将其删除,以查看是否确实如此。希望我可以节省至少一个人浪费我的时间。


24

结合几个答案,这对我在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

21

还有一些简单的方法可以手动控制缩小(和其他功能)。这是使用的新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)。


13

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

目标:始终捆绑文件,在发生这种情况时禁用JS和CSS最小化,<compilation debug="true" ... />并始终对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()));
     ...
}

7

如果将以下属性设置为false,则它将禁用捆绑和最小化。

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

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

我只是不明白,当我关闭此功能后,为什么我的较少文件会转换为CSS?启用优化后,捆绑较少的文件将不再起作用。
FrenkyB

5

以下是按组合禁用缩小功能的方法:

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-bundle(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在字体等方面起作用。但这是另一回事。


4

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

非常感谢本文,这为我提供了用于创建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文件创建一个可选的渲染器也几乎不需要更新到此帮助器。


1
效果很好。如果你想要的网址更改时,文件被更新,您可以更改CssTemplate喜欢的东西"<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />",改变sb.AppendFormat线对像sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo

没错,我们在工作中做了很多类似的事情。我们将一个公共静态字符串JSVersion放入了Global.asax类中,该类提取了执行程序集的maj / min / build / rev。然后,我们像这样引用它:<script type =“ text / javascript” src =“ Scripts / jsfile_name.js <%= Global.JSVersion%>”> </ script>
James Eby

3

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

所以如果你发现

BundleTable.EnableOptimizations = true;

转动它false


2
这确实禁用了缩小功能,但也完全禁用了绑定功能,我认为至少应该注意这一点。
约翰·帕维克

1

如果您使用的是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>
}

这将是一个动态网址,例如 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>

1
文件名不会在每次编译时更改。它基于文件内容,因此只要文件更改,它就会更改。
Jim Raden 2014年

1

这可能会在未来随着新的框架,成为有用的人,当设置通过VS,得到了默认web.configweb.Debug.configweb.Release.config。在中,web.release.config您会发现以下行:

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

这似乎覆盖了我所做的任何内联更改。我注释掉了这一行,我们很吃力(就在“发布”版本中看到未压缩的代码而言)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.