Bundles ASP.NET comment désactiver la minification

185

J'ai debug="true"dans mes deux web.config (s) , et je ne veux tout simplement pas que mes bundles soient minifiés, mais rien de ce que je fais ne semble le désactiver. J'ai essayé enableoptimisations=false, voici mon code:

//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))
Baconbeastnz
la source
2
@ RickAnd-MSFT La demande est de savoir comment activer le regroupement tout en désactivant la minification. L'utilisation de web.config debug = true / false ou EnableOptimizations active uniquement les deux ou les deux. La réponse de Martin Devillers permet d'activer le regroupement alors que la minification est désactivée
Guymid
2
aussi pour moi .... pour le fichier 'x.js' dans le bundle, assurez-vous qu'il n'y a PAS de fichier 'x.min.js' dans le dossier sinon bien que vous ayez supprimé la transformation de minification .. le regroupement servira le Fichier 'pré' minifié, par exemple si vous avez 'angular.js' alors SUPPRIMER 'angular.min.js' ;-)
stooboo

Réponses:

137

Si vous avez debug="true"dans web.config et que vous utilisez Scripts/Styles.Renderpour référencer les bundles dans vos pages, cela devrait désactiver le regroupement et la minification. BundleTable.EnableOptimizations = falsedésactivera toujours à la fois le regroupement et la minification (quel que soit l'indicateur de débogage vrai / faux).

N'utilisez-vous peut-être pas les Scripts/Styles.Renderaides? Si vous affichez directement des références au bundle via, BundleTable.Bundles.ResolveBundleUrl()vous obtiendrez toujours le contenu minifié / regroupé.

Hao Kung
la source
12
À partir de cette réponse, je ne sais pas comment désactiver uniquement la minification et laisser le regroupement en place - est-ce possible?
Adam Tuliper - MSFT
33
Pour ce faire, le plus simple serait de changer les Script / StyleBundles pour les Bundles simples qui n'ont pas de Transform défini par défaut, cela désactiverait la minification mais toujours le bundle. Notez que vous devez toujours avoir EnableOptimizations défini sur true pour que le regroupement se produise.
Hao Kung
2
aussi pour moi .... pour le fichier 'x.js' dans le bundle, assurez-vous qu'il n'y a PAS de fichier 'x.min.js' dans le dossier sinon bien que vous ayez supprimé la transformation de minification .. le regroupement servira le Fichier 'pré' minifié, par exemple si vous avez 'angular.js' alors SUPPRIMER 'angular.min.js' ;-)
stooboo
1
@stooboo C'est ce qui a résolu le problème pour moi, mais vous n'avez rien à supprimer. Incluez simplement le fichier non min.
OneHoopyFrood
2
EnableOptimizations = false- où appartient ce code?
alex
158

Les directives de compilation conditionnelle sont vos amis:

#if DEBUG
            var jsBundle = new Bundle("~/Scripts/js");
#else
            var jsBundle = new ScriptBundle("~/Scripts/js");
#endif
Martin Devillers
la source
16
En fait, je pense qu'il l'a cloué - pour simplement désactiver la minification, utilisez un bundle selon Hao, sinon utilisez ScriptBundle qui regroupe et minifie, non?
Adam Tuliper - MSFT
1
C'est une excellente solution lorsque vous souhaitez référencer le bundle par son URI de référence de bundle pour des choses comme le chargement via RequireJS sans utiliser le propre système de bundling / minification de RequireJS.
Norman H
1
Je vois des choses comme Adam, je comprends le ScriptBundle comme un Bundle amélioré, donc puisque vous voulez ajouter une référence de base (pas de post-opérations spécifiques), Bundle me semble un bon moyen de désactiver la minification sur un bundle particulier.
Charles HETIER
6
@ RickAnd-MSFT Je pense que vous vous méprenez sur le but de ce code qui permet le regroupement + pas de minification en mode débogage et le regroupement + minification en mode version. L'utilisation de web.config debug = true / false ou EnableOptimizations active uniquement les deux ou les deux. J'ai lu votre commentaire et j'ai rejeté cette solution de Martin, seulement pour découvrir que c'est en fait un très bon moyen d'avoir un regroupement sans minification
guymid
-1 cette "solution" est au mieux un palliatif. En réalité, même si cela fonctionne, cela conduit à un code très intenable. Mais ce n'est pas la pire chose à ce sujet. L'utilisation de "Bundle" conduit à ce que les actifs soient remis par le serveur avec le type mime défini sur "text / html" au lieu de "text / javascript". Si vous appliquez cette approche pour regrouper des fichiers css, vous jouez avec Fire en mode débogage. Ne fais pas ça. Ne le fais pas. Voir ma réponse pour une approche plus saine qui fonctionne dans les versions de production.
XDS le
89

Pour désactiver le regroupement et la minification, placez simplement votre fichier .aspx (cela désactivera l'optimisation même si debug=truedans web.config )

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c # .net

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

Si vous mettez EnableOptimizations = truecela, cela regroupera et minifiera même si debug=truedans web.config

manuel
la source
2
C'est la seule chose qui a résolu le problème pour moi. J'avais debug="true"et le droit Script.Rendermais cela ne fonctionnait toujours pas. Notez également que cela ne servira pas de fichiers .min.js, assurez-vous donc d'inclure des copies non réduites du code de dépendance.
OneHoopyFrood
2
@TCC: ai-je tort de penser que la syntaxe vb.net devrait avoir une majuscule False?
jeremysawesome
@jeremysawesome oh ouais je pense que c'est correct, bon point :-) Je ne suis pas un programmeur VB très souvent donc je n'ai même pas remarqué ...
TCC
1
La première ligne doit être "... même si debug = false" non?
UnionP
2
vb.Net ne se soucie pas du cas, False = false, comme .tostring () = .toString ()
manuel
68

Vous pouvez désactiver la minification dans vos bundles simplement en effaçant vos transformations.

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

Personnellement, j'ai trouvé cela utile lorsque je voulais regrouper tous mes scripts dans un seul fichier, mais que j'avais besoin de lisibilité pendant les phases de débogage.

muglio
la source
1
-1 Voici des dragons: Arracher le JsMinifier / CssMinifier arrache également le mécanisme interne qui définit le type mime sur "text / css" ou "text / javascript". Cela ne pose pas de problèmes en mode débogage / version, mais cela fait des ravages dans les bundles css dans le contexte des builds publiés (ou déploiements en direct): Chrome et Firefox refusent de charger lesdits bundles css en déclarant que leurs types mime sont définis sur "text / html" au lieu de "text / css". Avec js-bundles, les choses s'entraînent d'une manière ou d'une autre, mais il est au mieux louche d'avoir un js-bundle remis en tant que "text / html" (<- sérieusement?). Voir ma réponse pour la bonne approche.
XDS du
28

J'ai essayé beaucoup de ces suggestions, mais les remarques semblaient fonctionner. J'ai perdu pas mal d'heures pour découvrir que c'était mon erreur:

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

Cela m'a toujours permis de réduire et de regrouper le javascript, peu importe ce que j'ai essayé. Au lieu de cela, j'aurais dû utiliser ceci:

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

Le «~» supplémentaire l'a fait. Je l'ai même supprimé à nouveau dans un seul cas pour voir si c'était vraiment ça. C'était ... j'espère pouvoir sauver au moins une personne les heures que j'ai gaspillées là-dessus.

pseudo
la source
Wow, je
deviens
24

Combinez plusieurs réponses, cela fonctionne pour moi dans 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
Jeff Tian
la source
21

Il existe également un moyen simple de contrôler manuellement la minification (et d'autres fonctionnalités). C'est le nouveau transformateur CssMinify () utilisant, comme ceci:

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

C'est pratique lorsque vous souhaitez avoir une partie spéciale de certains bundles à minimiser. Disons que vous utilisez des styles standard (jQuery), qui vous mettent sous vos pieds (en leur demandant beaucoup de requêtes de navigateur excessives), mais que vous souhaitez conserver votre propre feuille de style non réduite. (La même chose - avec javascript).

Agat
la source
13

J'ai combiné quelques réponses données par d'autres dans cette question pour trouver une autre solution alternative.

Objectif: toujours regrouper les fichiers, désactiver la minification JS et CSS dans le cas où <compilation debug="true" ... />et toujours appliquer une transformation personnalisée au bundle CSS.

Ma solution :

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

2) Dans la méthode 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()));
     ...
}
Vince Horst
la source
7

Si vous définissez la propriété suivante sur false, cela désactivera à la fois le regroupement et la minification.

Dans le fichier Global.asax.cs , ajoutez la ligne comme mentionné ci-dessous

protected void Application_Start()
{
    System.Web.Optimization.BundleTable.EnableOptimizations = false;
}
marvelTracker
la source
Je ne comprends tout simplement pas pourquoi mes fichiers moins sont transformés en css lorsque cette fonctionnalité est désactivée? Lorsque j'active l'optimisation, regrouper moins de fichiers ne fonctionne plus.
FrenkyB
5

Voici comment désactiver la minification par lot:

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

Note de bas de page: Les chemins utilisés pour vos bundles ne doivent coïncider avec aucun chemin réel dans vos versions publiées, sinon rien ne fonctionnera. Assurez-vous également d'éviter d'utiliser .js, .css et / ou '.' et '_' n'importe où dans le nom du bundle. Gardez le nom aussi simple et direct que possible, comme dans l'exemple ci-dessus.

Les classes d'assistance sont présentées ci-dessous. Notez que pour rendre ces classes à l'épreuve du temps, nous supprimons chirurgicalement les instances de minification js / css au lieu d'utiliser .clear () et nous insérons également une transformation de type mime sans laquelle les versions de production risquent de rencontrer des problèmes, en particulier lorsque il s'agit de remettre correctement les bundles css (Firefox et Chrome rejettent les bundles css avec le type mime défini sur "text / html" qui est la valeur par défaut):

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

Pour que tout cela fonctionne, vous devez installer (via nuget):

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

Et votre web.config devrait être enrichi comme ceci:

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

Notez que vous devrez peut-être prendre des mesures supplémentaires pour faire fonctionner vos ensembles css en termes de polices, etc. Mais c'est une autre histoire.

XDS
la source
4

Juste pour compléter les réponses déjà données, si vous souhaitez également NE PAS minifier / obscurcir / concaténer CERTAINS fichiers tout en permettant le regroupement complet et la minification pour d'autres fichiers, la meilleure option est d'utiliser un moteur de rendu personnalisé qui lira le contenu d'un bundle particulier (s) et restituer les fichiers dans la page plutôt que de rendre le chemin virtuel du bundle. J'avais personnellement besoin de cela parce que IE 9 était $ *% @ ing le lit lorsque mes fichiers CSS étaient regroupés même avec la minification désactivée .

Merci beaucoup à cet article , qui m'a donné le point de départ du code que j'ai utilisé pour créer un rendu CSS qui rendrait les fichiers pour le CSS tout en permettant au système de rendre mes fichiers javascript regroupés / minifiés / obscurcis.

Création de la classe d'assistance statique:

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

}

Puis dans le fichier de disposition du rasoir:

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

au lieu de la norme:

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

Je suis sûr que la création d'un moteur de rendu facultatif pour les fichiers javascript nécessiterait également peu de mise à jour vers cet assistant.

James Eby
la source
1
Fonctionne bien. Si vous voulez que les URL changent lorsque les fichiers sont mis à jour, vous pouvez changer CssTemplatepour quelque chose comme "<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />"et changer la sb.AppendFormatligne en quelque chose commesb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo
Certes, nous avons fait quelque chose comme ça au travail. Nous avions une chaîne statique publique appelée JSVersion que nous avons placée dans la classe Global.asax qui tirait le maj / min / build / rev de l'assembly en cours d'exécution. Nous l'avons ensuite référencé comme suit: <script type = "text / javascript" src = "Scripts / jsfile_name.js <% = Global.JSVersion%>"> </script>
James E par
3

Rechercher un EnableOptimizationsmot-clé dans votre projet

Donc si vous trouvez

BundleTable.EnableOptimizations = true;

tournez-le false.

BJ Patel
la source
2
Cela désactive la minification, mais cela désactive également complètement le regroupement, ce qui, à mon avis, devrait au moins être noté.
John Pavek
1

Si vous utilisez la transformation CSS LESS / SASS, il existe une option useNativeMinificationqui peut être définie sur false pour désactiver la minification (dans web.config). Pour mes besoins, je le change simplement ici quand j'en ai besoin, mais vous pouvez utiliser les transformations web.config pour toujours l'activer lors de la version de version ou peut-être trouver un moyen de le modifier dans le code.

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

Astuce: le but est de visualiser votre CSS, ce que vous pouvez faire dans les outils d'inspection du navigateur ou en ouvrant simplement le fichier. Lorsque le regroupement est activé, ce nom de fichier change à chaque compilation, donc je mets ce qui suit en haut de ma page afin que je puisse voir mon CSS compilé facilement dans une nouvelle fenêtre de navigateur à chaque fois qu'il change.

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

ce sera une URL dynamique quelque chose comme https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


Mise à jour: j'ai créé une transformation web.config pour la définir sur true pour moi pendant le déploiement / la version de la version

  <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>
Simon_Weaver
la source
1
Le nom de fichier ne change PAS à chaque compilation. Il est basé sur le contenu du fichier, donc il change chaque fois que le fichier change.
Jim Raden
1

Cela peut être utile à quelqu'un à l'avenir le nouveau cadre, lorsque la configuration par VS, obtient une valeur par défaut web.config, web.Debug.configet web.Release.config. Dans le web.release.configvous trouverez cette ligne:

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

cela semblait remplacer toutes les modifications en ligne que j'avais apportées. J'ai commenté cette ligne et nous étions saufs (en termes de voir du code non minifié dans une version "release")

Mutmatt
la source