Pakiety ASP.NET, jak wyłączyć minimalizację


185

Mam debug="true"oba pliki web.config i po prostu nie chcę, aby moje pakiety zostały zminimalizowane, ale nic, co robię, nie wydaje się, aby je wyłączyć. Próbowałem enableoptimisations=false, oto mój kod:

//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 Żądanie dotyczy włączenia pakietowania przy wyłączonej minimalizacji. Użycie web.config debug = true / false lub EnableOptimizations włącza lub wyłącza oba. Odpowiedź Martina Devillersa pozwala na włączenie pakietowania, gdy minifikacja jest wyłączona
guymid

2
również dla mnie .... dla pliku „x.js” w pakiecie upewnij się, że NIE ma pliku „x.min.js” w folderze, w przeciwnym razie mimo usunięcia transformacji minifikacji. pakietowanie będzie obsługiwać „wstępnie” zminimalizowany plik, np. jeśli masz „angular.js”, a następnie USUŃ „angular.min.js” ;-)
stooboo

Odpowiedzi:


137

Jeśli masz debug="true"w web.config i korzystania Scripts/Styles.Renderodwołać wiązek w swoich stronach, że należy wyłączyć zarówno wiązania i minifikacji. BundleTable.EnableOptimizations = falsezawsze wyłącza zarówno pakowanie, jak i minimalizację (niezależnie od debugowanej flagi true / false).

Być może nie używasz Scripts/Styles.Renderpomocników? Jeśli bezpośrednio renderujesz odniesienia do pakietu BundleTable.Bundles.ResolveBundleUrl(), zawsze otrzymasz zminimalizowaną / powiązaną zawartość.


12
Na podstawie tej odpowiedzi nie jestem pewien, jak wyłączyć tylko minimalizację i pozostawić pakietowanie na miejscu - czy to możliwe?
Adam Tuliper - MSFT

33
Aby to zrobić, najłatwiej byłoby zmienić Script / StyleBundles na zwykłe pakiety, które nie mają domyślnie ustawionej transformacji, to wyłączałoby minimalizację, ale nadal wiązkę. Pamiętaj, że aby włączyć pakiet, nadal musisz mieć wartość EnableOptimizations ustawioną na true.
Hao Kung,

2
również dla mnie .... dla pliku „x.js” w pakiecie upewnij się, że NIE ma pliku „x.min.js” w folderze, w przeciwnym razie mimo usunięcia transformacji minifikacji. pakiet będzie obsługiwał „wstępnie” zminimalizowany plik, np. jeśli masz „angular.js”, a następnie USUŃ „angular.min.js” ;-)
stooboo

1
@stooboo To właśnie mnie naprawiło, ale nie musisz niczego usuwać. Wystarczy dołączyć plik inny niż min.
OneHoopyFrood

2
EnableOptimizations = false- gdzie należy ten kod?
alex

158

Wytyczne dotyczące kompilacji są Twoim przyjacielem:

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

16
Właściwie myślę, że go przybił - aby wyłączyć minifikację, użyj pakietu zgodnie z Hao, w przeciwnym razie użyj ScriptBundle, który zawiera i minimalizuje, nie?
Adam Tuliper - MSFT

1
Jest to świetne rozwiązanie, gdy chcesz odwoływać się do pakietu za pomocą jego identyfikatora URI, np. Ładowanie przez RequireJS bez korzystania z własnego systemu pakietowania / minimalizacji RequireJS.
Norman H

1
Widzę takie rzeczy jak Adam, rozumiem ScriptBundle jako ulepszony pakiet, więc ponieważ chcesz dodać podstawowe odniesienie (bez konkretnych operacji po), pakiet wydaje mi się dobrym sposobem na wyłączenie minifikacji w określonym pakiecie.
Charles HETIER,

6
@ RickAnd-MSFT Myślę, że nie rozumiesz celu tego kodu, który umożliwia pakowanie + brak minimalizacji w trybie debugowania oraz pakowanie + minimalizowanie w trybie zwolnienia. Użycie web.config debug = true / false lub EnableOptimizations włącza lub wyłącza oba. Przeczytałem twój komentarz i odrzuciłem to rozwiązanie Martina, tylko po to, aby dowiedzieć się, że jest to naprawdę bardzo dobry sposób na pakowanie bez minimalizacji
guymid

-1 to „rozwiązanie” jest co najwyżej stop-gap. W rzeczywistości, nawet jeśli działa, prowadzi do bardzo nieusuwalnego kodu. Ale to nie jest najgorsze. Użycie „Pakietu” prowadzi do przekazania zasobów przez serwer z typem MIME ustawionym na „text / html” zamiast „text / javascript”. Jeśli zastosujesz to podejście do łączenia plików css, grasz ogniem w trybie debugowania. Nie rób Po prostu nie. Zobacz moją odpowiedź na zdrowsze podejście, które działa w kompilacjach produkcyjnych.
XDS

89

Aby wyłączyć pakietowanie i minimalizację, po prostu umieść ten plik .aspx (spowoduje to wyłączenie optymalizacji, nawet jeśli debug=truew pliku web.config )

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c # .net

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

Jeśli umieścisz EnableOptimizations = trueto spakuje i zminimalizuje, nawet jeśli debug=truew web.config


2
To jedyna rzecz, która naprawiła dla mnie ten problem. Miałem debug="true"i słusznie, Script.Renderale wciąż nie działało. Pamiętaj również, że nie będzie to serwer żadnych plików .min.js, więc pamiętaj o dołączeniu nieuprawnionych kopii kodu zależności.
OneHoopyFrood

2
@TCC: Czy mylę się myśląc, że składnia vb.net powinna mieć kapitał False?
jeremysawesome

@jeremysawesome o tak, myślę, że to prawda, dobra uwaga :-) Nie jestem często programistą VB, więc nawet nie zauważyłem ...
TCC 20'15

1
Pierwsza linia powinna brzmieć „... nawet jeśli debugowanie = fałsz” nie?
UnionP

2
vb.Net nie dba o wielkość liter, False = false, jak .tostring () = .toString ()
manuel

67

Możesz wyłączyć minifikację w swoich pakietach, po prostu usuwając transformacje.

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

Osobiście uważam to za przydatne, gdy chcę spakować wszystkie moje skrypty w jednym pliku, ale potrzebowałem czytelności podczas faz debugowania.


1
-1 Oto smoki: Zdzieranie JsMinifier / CssMinifier wyrywa także wewnętrzny mechanizm, który ustawia typ mime na „text / css” lub „text / javascript”. Nie powoduje to problemów w trybie debugowania / wydania, ale powoduje spustoszenie w pakietach css w kontekście opublikowanych kompilacji (inaczej wdrożeń na żywo): Chrome i Firefox odmawiają załadowania wspomnianych pakietów css, stwierdzając, że ich typy MIME są ustawione na „text / html” zamiast „text / css”. Z pakietami js jakoś ćwiczysz, ale najlepiej jest podejrzewać, że pakiet js jest przekazywany jako „text / html” (<- poważnie?). Zobacz moją odpowiedź na prawidłowe podejście.
XDS,

28

Próbowałem wiele z tych sugestii, ale zauważyłem, że zadziałało. Zmarnowałem kilka godzin, aby dowiedzieć się, że to mój błąd:

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

Zawsze mam zminimalizowany i dołączony javascript, bez względu na to, czego próbowałem. Zamiast tego powinienem był użyć tego:

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

Dodatkowe „~” to zrobiło. Nawet usunąłem go ponownie tylko w jednym przypadku, aby zobaczyć, czy tak naprawdę było. To było ... mam nadzieję, że mogę zaoszczędzić przynajmniej jednej osobie godziny, które na to straciłem.


Wow, oszalałam przez ostatnie 3 godziny ...
Bodokh

24

Połącz kilka odpowiedzi, to działa dla mnie w 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

Istnieje również prosty sposób ręcznego kontrolowania minimalizacji (i innych funkcji). Jest to nowy transformator CssMinify (), wykorzystujący:

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

Jest to wygodne, gdy chcesz mieć specjalne pakiety tylko do zminimalizowania. Załóżmy, że używasz niektórych standardowych stylów (jQuery), które dostają się pod twoje stopy (przyjmując do nich zbyt wiele żądań przeglądarki), ale chcesz zachować nieupoważniony własny arkusz stylów. (To samo - z javascript).


13

Połączyłem kilka odpowiedzi udzielonych przez inne osoby w tym pytaniu, aby znaleźć inne alternatywne rozwiązanie.

Cel: zawsze wiązać pliki, wyłączać minimalizację JS i CSS w przypadku, gdy<compilation debug="true" ... /> i zawsze stosować niestandardową transformację do pakietu CSS.

Moje rozwiązanie :

1) W pliku web.config : <compilation debug="true" ... />

2) W metodzie 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

Jeśli ustawisz następującą właściwość na false, spowoduje to wyłączenie zarówno sprzedaży pakietowej, jak i minimalizacji.

W pliku Global.asax.cs dodaj wiersz, jak wspomniano poniżej

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

Po prostu nie rozumiem, dlaczego moje mniej plików są przekształcane w css, gdy mam tę funkcję wyłączoną? Po włączeniu optymalizacji pakowanie mniejszej liczby plików już nie działa.
FrenkyB

5

Oto jak wyłączyć minimalizację dla poszczególnych pakietów:

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

Uwaga: ścieżki użyte w twoich pakietach nie mogą pokrywać się z żadną rzeczywistą ścieżką w opublikowanych kompilacjach, w przeciwnym razie nic nie zadziała. Pamiętaj także, aby unikać używania plików .js, .css i / lub „.” i „_” w dowolnym miejscu w nazwie pakietu. Zachowaj nazwę tak prostą i zrozumiałą, jak to możliwe, jak w powyższym przykładzie.

Klasy pomocników pokazano poniżej. Zauważ, że aby uczynić te klasy przyszłymi, usuwamy chirurgicznie instancje minimalizujące js / css zamiast .clear (), a także wstawiamy transformację ustawiającą typy MIME, bez której kompilacje produkcyjne będą miały problemy, szczególnie gdy chodzi o prawidłowe przekazywanie pakietów css (firefox i chrome odrzucają pakiety css z typem MIME ustawionym na „text / html”, który jest domyślny):

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

Aby to wszystko działało, musisz zainstalować (przez nuget):

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

A twój web.config powinien zostać wzbogacony w następujący sposób:

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

Pamiętaj, że może być konieczne wykonanie dodatkowych kroków, aby Twoje pakiety css działały pod względem czcionek itp. Ale to inna historia.


4

Aby uzupełnić już podane odpowiedzi, jeśli chcesz NIE minimalizować / zaciemniać / konkatenować NIEKTÓRE pliki, jednocześnie pozwalając na pełne wiązanie i minimalizowanie innych plików, najlepszą opcją jest skorzystanie z niestandardowego mechanizmu renderującego, który będzie odczytywał zawartość konkretnego pakietu (s) i renderuj pliki na stronie zamiast renderować wirtualną ścieżkę pakietu. Osobiście tego wymagałem, ponieważ IE 9 był $ *% @ w łóżku, gdy moje pliki CSS były pakowane nawet przy wyłączonej funkcji minimalizacji .

Bardzo dziękuję temu artykułowi , który dał mi punkt wyjścia do kodu, którego użyłem do utworzenia Renderera CSS, który renderowałby pliki dla CSS, ale nadal pozwalał systemowi renderować moje pliki javascript w pakiecie / zminimalizowane / zaciemnione.

Utworzono statyczną klasę pomocnika:

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

}

Następnie w pliku układu maszynki do golenia:

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

zamiast standardu:

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

Jestem pewien, że utworzenie opcjonalnego mechanizmu renderującego dla plików javascript również nie wymagałoby aktualizacji do tego pomocnika.


1
Działa dobrze. Jeśli chcesz, aby adresy URL zmieniały się podczas aktualizacji plików, możesz zmienić CssTemplatena coś podobnego "<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />"i zmienić sb.AppendFormatwiersz na coś takiegosb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo

To prawda, że ​​zrobiliśmy coś takiego w pracy. Mieliśmy publiczny ciąg statyczny o nazwie JSVersion, który umieściliśmy w klasie Global.asax, który pobrał maj / min / build / rev wykonującego się zestawu. Odnieśliśmy się do tego w następujący sposób: <script type = "text / javascript" src = "Scripts / jsfile_name.js <% = Global.JSVersion%>"> </script>
James Eby

3

Szukaj EnableOptimizations słowo kluczowe w swoim projekcie

Więc jeśli znajdziesz

BundleTable.EnableOptimizations = true;

obróć to false.


2
To wyłącza minifikację, ale także całkowicie wyłącza pakietowanie, co moim zdaniem należy przynajmniej zauważyć.
John Pavek

1

Jeśli używasz transformacji LESS / SASS CSS, useNativeMinificationmożesz ustawić opcję false, aby wyłączyć minifikację (w pliku web.config). Dla moich celów po prostu zmieniam go tutaj, kiedy jest to konieczne, ale możesz użyć transformacji web.config, aby zawsze włączać go w wersji kompilacji lub znaleźć sposób modyfikacji w kodzie.

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

Wskazówka: Chodzi o to, aby wyświetlić Twój CSS, co możesz zrobić w przeglądarce narzędzi inspekcji lub po prostu otwierając plik. Gdy pakietowanie jest włączone, nazwy plików zmieniają się przy każdym kompilacji, dlatego umieszczam poniższe na górze mojej strony, aby za każdym razem móc przeglądać skompilowany CSS w nowym oknie przeglądarki.

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

będzie to dynamiczny adres URL podobny do tego https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


Aktualizacja: Utworzyłem transformację web.config, aby ustawić ją na wartość true podczas kompilacji wdrażania / wydania

  <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
Nazwa pliku NIE zmienia się przy każdym kompilacji. Opiera się na zawartości pliku, więc zmienia się przy każdej zmianie pliku.
Jim Raden

1

Może to stać się przydatne do kogoś w przyszłości nowych ram, gdy konfiguracja przez VS, staje się domyślną web.config, web.Debug.configa web.Release.config. W linii web.release.configznajdziesz:

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

zdawało się, że to zastępuje wszelkie wprowadzone przeze mnie zmiany. Skomentowałem tę linię i byliśmy powściągliwi (jeśli chodzi o wyświetlanie niezmodyfikowanego kodu w kompilacji „release”)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.