Pacchetti ASP.NET su come disabilitare la minificazione


185

Ho debug="true"entrambi i miei web.config e non voglio minimizzare i miei bundle, ma nulla che faccio sembra disabilitarlo. Ho provato enableoptimisations=false, ecco il mio codice:

//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 La richiesta è come abilitare il raggruppamento mentre la minificazione è disabilitata. L'uso di web.config debug = true / false o EnableOptimizations consente di attivare o disattivare entrambi. La risposta di Martin Devillers consente di abilitare il raggruppamento mentre la minificazione è disabilitata
guymid,

2
anche per me .... per il file 'x.js' nel bundle assicurati che NON ci sia un file 'x.min.js' nella cartella altrimenti, anche se hai rimosso la trasformazione di minificazione .. il raggruppamento servirà il file pre-minificato, ad esempio se si dispone di 'angular.js', quindi ELIMINARE 'angular.min.js' ;-)
stooboo

Risposte:


137

Se hai debug="true"in web.config e stai usando Scripts/Styles.Rendercome riferimento i bundle nelle tue pagine, questo dovrebbe disattivare sia il raggruppamento che la minimizzazione. BundleTable.EnableOptimizations = falsedisattiverà sempre sia il raggruppamento che la minificazione (indipendentemente dal flag true / false del debug).

Forse non stai usando gli Scripts/Styles.Renderhelper? Se si BundleTable.Bundles.ResolveBundleUrl()esegue il rendering diretto dei riferimenti al pacchetto tramite, si otterrà sempre il contenuto ridotto / raggruppato.


12
Da questa risposta, non sono sicuro di come disattivare solo la minificazione e lasciare il raggruppamento in atto - è possibile?
Adam Tuliper - MSFT,

33
Per fare ciò, il modo più semplice sarebbe cambiare Script / StyleBundles per pacchetti semplici che non hanno Transform impostato per impostazione predefinita, questo disattiverebbe la minificazione ma comunque raggrupperebbe. Nota che dovresti comunque avere EnableOptimizations impostato su true perché avvenga il raggruppamento.
Hao Kung,

2
anche per me .... per il file 'x.js' nel bundle assicurati che NON ci sia un file 'x.min.js' nella cartella altrimenti, anche se hai rimosso la trasformazione di minificazione .. il raggruppamento servirà il file 'pre' minificato, ad esempio se si dispone di 'angular.js', quindi ELIMINARE 'angular.min.js' ;-)
stooboo

1
@stooboo Questo è ciò che l'ha risolto per me, ma non è necessario eliminare nulla. Includi solo il file non min.
OneHoopyFrood,

2
EnableOptimizations = false- dove appartiene questo codice?
alex,

158

Le direttive sulla compilazione condizionale sono le tue amiche:

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

16
In realtà penso che l'abbia inchiodato - al fine di disattivare la minificazione, utilizzare un pacchetto secondo Hao, altrimenti utilizzare ScriptBundle che raggruppa e minimizza, no?
Adam Tuliper - MSFT,

1
Questa è un'ottima soluzione quando si desidera fare riferimento al pacchetto tramite l'URI di riferimento del pacchetto per cose come il caricamento tramite RequireJS senza utilizzare il proprio sistema di raggruppamento / minificazione di RequireJS.
Norman H,

1
Vedo cose come Adam, capisco ScriptBundle come un pacchetto avanzato, quindi poiché vuoi aggiungere un riferimento di base (senza post-operazioni specifiche), il pacchetto mi sembra un buon modo per disabilitare la minificazione su un particolare pacchetto.
Charles HETIER,

6
@ RickAnd-MSFT Penso che tu stia fraintendendo lo scopo di questo codice che consente il raggruppamento + nessuna riduzione in modalità debug e il raggruppamento + riduzione in modalità di rilascio. L'uso di web.config debug = true / false o EnableOptimizations consente di attivare o disattivare entrambi. Ho letto il tuo commento e ho respinto questa soluzione di Martin, solo per scoprire che in realtà è un ottimo modo per avere un raggruppamento senza minificazione
guymid,

-1 questa "soluzione" è al massimo uno stop-gap. In realtà, anche se funziona, porta a un codice molto inimmaginabile. Ma questa non è la cosa peggiore. L'uso di "Bundle" comporta la consegna delle risorse dal server con il tipo mime impostato su "text / html" anziché "text / javascript". Se si applica questo approccio per raggruppare i file CSS, si sta giocando con il fuoco in modalità debug. Non farlo. Non farlo. Vedi la mia risposta per un approccio più salutare che funziona nelle build di produzione.
XDS

89

Per disabilitare il raggruppamento e la minificazione basta inserire questo file .aspx (questo disabiliterà l'ottimizzazione anche se debug=truein web.config )

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

C # .NET

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

Se lo metti EnableOptimizations = truequesto raggrupperà e minimizzerà anche se debug=truein web.config


2
Questa è l'unica cosa che ha risolto il problema per me. Avevo debug="true"e il diritto, Script.Renderma non funzionava ancora. Si noti inoltre che questo non server alcun file .min.js, quindi assicurarsi di includere copie non minime del codice di dipendenza.
OneHoopyFrood,

2
@TCC: sbaglio nel pensare che la sintassi di vb.net dovrebbe avere un capitale False?
jeremysawesome

@jeremysawesome oh yeah Penso che sia corretto, buon punto :-) Non sono un programmatore VB molto spesso, quindi non me ne sono nemmeno accorto ...
TCC

1
La prima riga dovrebbe essere "... anche se debug = false" no?
UnionP

2
vb.Net non si preoccupa del caso, False = false, come .tostring () = .toString ()
manuel

68

Puoi disattivare la minificazione nei tuoi bundle semplicemente cancellando le tue trasformazioni.

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

Personalmente l'ho trovato utile quando volevo raggruppare tutti i miei script in un singolo file ma avevo bisogno di leggibilità durante le fasi di debug.


1
-1 Ecco i draghi: strappare JsMinifier / CssMinifier strappa anche il meccanismo interno che imposta il tipo mime su "text / css" o "text / javascript". Ciò non causa problemi nella modalità debug / release ma provoca il caos nei bundle css nel contesto di build pubblicate (ovvero le distribuzioni live): Chrome e Firefox si rifiutano di caricare i bundle css dichiarando che i loro tipi mime sono impostati su "text / html" invece di "text / css". Con js-bundles le cose si allenano in qualche modo, ma è meglio avere un bundle js consegnato come "text / html" (<- sul serio?). Vedi la mia risposta per l'approccio corretto.
XDS

28

Ho provato molti di questi suggerimenti, ma la notazione sembrava funzionare. Ho perso parecchie ore solo per scoprire che questo era il mio errore:

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

Mi ha sempre minimizzato e raggruppato javascript, non importa quello che ho provato. Invece, avrei dovuto usare questo:

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

Il '~' extra lo ha fatto. L'ho anche rimosso di nuovo in una sola istanza per vedere se fosse davvero così. Speravo di poter salvare almeno una persona le ore che ho perso con questo.


Wow, sono impazzito nelle ultime 3 ore in questo ...
Bodokh,

24

Combina diverse risposte, questo funziona per me in 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

C'è anche un modo semplice per controllare manualmente la minificazione (e altre funzionalità). È il nuovo trasformatore CssMinify () che utilizza, in questo modo:

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

È utile quando si desidera avere alcuni pezzi speciali solo per essere minimizzati. Supponiamo che tu stia utilizzando alcuni stili standard (jQuery), che stanno arrivando sotto i tuoi piedi (rispondendo a molte richieste eccessive da parte del browser), ma vuoi mantenere non miniato il tuo foglio di stile. (Lo stesso - con javascript).


13

Ho combinato alcune risposte fornite da altri in questa domanda per trovare un'altra soluzione alternativa.

Obiettivo: raggruppare sempre i file, disabilitare la minificazione JS e CSS nel caso in cui <compilation debug="true" ... />e applicare sempre una trasformazione personalizzata al pacchetto CSS.

La mia soluzione :

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

2) Nel metodo 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

Se si imposta la proprietà seguente su false, verranno disabilitati sia il raggruppamento che la minificazione.

Nel file Global.asax.cs , aggiungi la riga come indicato di seguito

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

Semplicemente non capisco perché i miei meno file vengono trasformati in CSS quando ho questa funzione disattivata? Quando abilito l'ottimizzazione, il raggruppamento di meno file non funziona più.
FrenkyB,

5

Ecco come disabilitare la minificazione in base al pacchetto:

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

Sidenote: i percorsi utilizzati per i bundle non devono coincidere con alcun percorso effettivo nelle build pubblicate, altrimenti non funzionerà nulla. Assicurati anche di evitare l'uso di .js, .css e / o '.' e '_' ovunque nel nome del pacchetto. Mantieni il nome il più semplice e diretto possibile, come nell'esempio sopra.

Le classi di aiuto sono mostrate di seguito. Si noti che al fine di rendere queste classi a prova di futuro rimuoviamo chirurgicamente le istanze di minimizzazione js / css invece di utilizzare .clear () e inseriamo anche una trasformazione setter di tipo mime senza la quale le build di produzione sono destinate a guastarsi, specialmente quando si tratta di consegnare correttamente i bundle css (firefox e chrome rifiutano i bundle css con tipo mime impostato su "text / html" che è l'impostazione predefinita):

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

Per far funzionare tutto questo è necessario installare (tramite nuget):

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

E il tuo web.config dovrebbe essere arricchito in questo modo:

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

Nota che potresti dover fare ulteriori passi per far funzionare i tuoi css-bundle in termini di font ecc. Ma questa è una storia diversa.


4

Solo per integrare le risposte già fornite, se anche NON si desidera minimizzare / offuscare / concatenare ALCUNI file pur consentendo il raggruppamento completo e la minificazione per altri file, l'opzione migliore è quella di utilizzare un renderer personalizzato che leggerà il contenuto di un particolare pacchetto (s) e renderizzare i file nella pagina anziché renderizzare il percorso virtuale del pacchetto. Personalmente ho richiesto questo perché IE 9 era $ *% @ sul letto quando i miei file CSS venivano raggruppati anche con la minificazione disattivata .

Grazie mille a questo articolo , che mi ha dato il punto di partenza per il codice che ho usato per creare un renderer CSS che renderebbe i file per il CSS ma consentirebbe comunque al sistema di rendere i miei file javascript raggruppati / minimizzati / offuscati.

Creata la classe helper statica:

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

}

Quindi nel file di layout del rasoio:

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

invece dello standard:

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

Sono sicuro che la creazione di un renderer opzionale per i file javascript richiederebbe poco anche per l'aggiornamento a questo aiuto.


1
Funziona bene. Se vuoi che gli URL cambino quando i file vengono aggiornati, puoi cambiare CssTemplatein qualcosa di simile "<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />"e cambiare la sb.AppendFormatlinea in qualcosa di similesb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo

È vero, abbiamo fatto qualcosa di simile al lavoro. Avevamo una stringa statica pubblica chiamata JSVersion che inserivamo nella classe Global.asax che estraeva il maj / min / build / rev dell'assembly in esecuzione. Lo abbiamo quindi fatto riferimento in questo modo: <script type = "text / javascript" src = "Scripts / jsfile_name.js <% = Global.JSVersion%>"> </script>
James Eby,

3

Cerca la EnableOptimizationsparola chiave nel tuo progetto

Quindi se lo trovi

BundleTable.EnableOptimizations = true;

trasformalo false.


2
Questo disabilita la minificazione, ma disabilita anche il raggruppamento interamente, che penso che dovrei almeno essere notato.
John Pavek,

1

Se stai usando la trasformazione CSS LESS / SASS c'è un'opzione useNativeMinificationche può essere impostata su false per disabilitare la minificazione (in web.config). Per i miei scopi, lo cambio qui solo quando è necessario, ma è possibile utilizzare le trasformazioni web.config per abilitarlo sempre nella build di rilascio o forse trovare un modo per modificarlo nel codice.

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

Suggerimento: il punto è quello di visualizzare i CSS, cosa che puoi fare con gli strumenti di ispezione del browser o semplicemente aprendo il file. Quando il raggruppamento è abilitato, il nome di questo file cambia ad ogni compilazione, quindi inserisco quanto segue nella parte superiore della mia pagina in modo da poter visualizzare facilmente il mio CSS compilato in una nuova finestra del browser ogni volta che cambia.

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

questo sarà un URL dinamico qualcosa del genere https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


Aggiornamento: ho creato una trasformazione web.config per impostarla su true per me durante la compilazione di distribuzione / rilascio

  <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
Il nome file NON cambia ad ogni compilazione. Si basa sul contenuto del file, quindi cambia ogni volta che il file cambia.
Jim Raden,

1

Questo può diventare utile a qualcuno in futuro, come il nuovo quadro, quando l'installazione attraverso VS, ottiene un default web.config, web.Debug.confige web.Release.config. Nel web.release.configtroverai questa riga:

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

questo sembrava sovrascrivere qualsiasi modifica in linea che ho apportato. Ho commentato questa riga ed eravamo sugo (in termini di vedere il codice non minimizzato in una build "release")

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.