Comment désactiver la minification Javascript / CSS dans ASP.NET MVC 4 Beta

J'essaye simplement ASP.NET MVC 4 mais je ne peux pas comprendre comment désactiver la fonction de minification Javascript / CSS. Surtout pour l'environnement de développement, cela aidera grandement à déboguer. J'imagine qu'il s'agirait d'un changement dans web.config, mais puisque ASP.NET MVC 4 est encore en phase bêta pour le moment, il n'y a vraiment pas beaucoup d'informations là-bas. J'apprécierais si quelqu'un peut aider ou pointer vers le bon blog, etc.

Dans Global.asax.cs

#if DEBUG foreach (var bundle in BundleTable.Bundles) { bundle.Transform = new NoTransform(); } #endif 

Une autre option serait de créer un assistant HTML que vous pourriez utiliser pour créer le script et lier des balises. Voici ce que j'ai mis en place pour le Javascript, ce qui peut également être fait pour le CSS:

 public static class BundleHelper { public static MvcHtmlString JsBundle(this HtmlHelper helper, string bundlePath) { var jsTag = new TagBuilder("script"); jsTag.MergeAttribute("type", "text/javascript"); return ReferenceBundle(helper, bundlePath, jsTag); } public static MvcHtmlString ReferenceBundle(this HtmlHelper helper, string bundlePath, TagBuilder baseTag) { var httpContext = helper.ViewContext.HttpContext; var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath); var htmlString = new StringBuilder(); if (bundle != null) { var bundleContext = new BundleContext(helper.ViewContext.HttpContext, BundleTable.Bundles, urlHelper.Content(bundlePath)); if (!httpContext.IsDebuggingEnabled) { baseTag.MergeAttribute("href", System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(bundlePath)); return new MvcHtmlString(baseTag.ToString()); } foreach (var file in bundle.EnumerateFiles(bundleContext)) { var basePath = httpContext.Server.MapPath("~/"); if (file.FullName.StartsWith(basePath)) { var relPath = urlHelper.Content("~/" + file.FullName.Substring(basePath.Length)); baseTag.MergeAttribute("href", relPath, true); htmlString.AppendLine(baseTag.ToString()); } } } return new MvcHtmlString(htmlString.ToString()); } } 

Maintenant, tout ce que vous devez faire est de l'appeler dans votre vue:

 <head> <meta charset="utf-8" /> <title>@ViewBag.Title - My ASP.NET MVC Application</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <link href="~/Content/css" rel="stylesheet" type="text/css" /> <link href="~/Content/themes/base/css" rel="stylesheet" type="text/css" /> @Html.JsBundle("~/scripts/js") <meta name="viewport" content="width=device-width" /> </head> 

Et il rendra les scripts comme des références distinctes, ou utilisera la nouvelle fonctionnalité de regroupement / minification en fonction de ce que le paramètre de débogage est dans votre web.config. J'ai utilisé un certain code de http://codecutout.com/resource-minify-bundling comme référence lors de la création de mon assistant si vous vouliez voir d'autres exemples. Leur aide est écrite un peu mieux, en lançant des exceptions lorsque des arguments non valides sont fournis, etc. … Je n'ai tout simplement pas encore tenté de nettoyer les mines.

Vous pouvez enregistrer vos propres paquets dans Global.asax et utiliser la classe NoTransform si vous ne voulez pas que le contenu soit minifié.

Personnellement, je ne veux pas que mon script soit transformé du tout. Je crée juste deux répertoires de script. Un avec les versions de script de débogage et un avec les versions minifiées téléchargées à l'origine.

Le MVC 4 hors de la boîte minifier (JsMinify) casse jQuery 1.7.1 pour Opera, donc je ne veux pas utiliser celui-ci. Je mets les lignes suivantes dans ma méthode Global.asax : Application_Start() :

 Bundle debugScripts = new Bundle("~/DebugScripts", new NoTransform("text/javascript")); debugScripts.AddDirectory("~/Scripts/Debug", "*.js"); BundleTable.Bundles.Add(debugScripts); Bundle productionScripts = new Bundle("~/ProductionScripts", new NoTransform("text/javascript")); productionScripts.AddDirectory("~/Scripts/Minified", "*.js"); BundleTable.Bundles.Add(productionScripts); 

Avec cela, je peux simplement ajouter une des deux lignes dans mon _layouts.cshtml :

 <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/DebugScripts")" type="text/javascript"></script> <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/ProductionScripts")" type="text/javascript"></script> 

Bien sûr, nous pourrions être un peu plus funky avec ceci en place. Nous pourrions générer un seul lot et, selon le type construit, sélectionnez les fichiers à inclure.

Après l'appel à EnableDefaultBundles() dans Global.asax, vous pouvez le faire …

  if ( ... running in development environment ...) { var registeredBundles = BundleTable.Bundles.GetRegisteredBundles(); foreach (var bundle in registeredBundles) { if (bundle.Transform is System.Web.Optimization.JsMinify) bundle.Transform = new NoTransform(); } } 

Pas joli (modification de l'état défini par le système), mais c'est beaucoup moins de code que toutes les autres suggestions, vous permet encore d'utiliser le comportement de regroupement standard et cela n'implique aucun changement dans vos vues.

Sur les versions plus récentes de ASP.NET MVC, ajoutez simplement

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

juste après

 BundleConfig.RegisterBundles(...); 

Vous pouvez l'éteindre à partir de la configuration:

 <system.web> <compilation debug="true" /> <!-- Lines removed for clarity. --> </system.web> 

http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

Je pense que ce serait correct, si une telle fonctionnalité sera disponible "hors de la boîte".

J'ai posté un commentaire sur UserVoice.com: http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/2702000-improve-system-web-optimization-bundle

Donnez-lui vos "voix".

Plutôt que de remplacer les instances de JsMinify et CssMinify, on peut plutôt utiliser des interfaces. Cette option n'était pas disponible dans les versions antérieures car le deuxième paramètre du constructeur était un type plutôt qu'une interface.

 IBundleTransform jsTransform; IBundleTransform cssTransform; #if DEBUG jsTransform = new NoTransform("text/javascript"); cssTransform = new NoTransform("text/css"); #else jsTransform = new JsMinify(); cssTransform = new CssMinify(); #endif Bundle jsBundle = new Bundle("~/JsB", jsTransform); Bundle cssBundle = new Bundle("~/CssB", cssTransform); 

Peut-être également à noter, pour les scripts qui sont livrés avec des versions minifiées et non minifiées, par exemple jQuery, on peut utiliser une méthode d'aide pour supprimer le ".min" pour les versions DEBUG pour faciliter le débogage:

 private string Min(string scriptNameIncludingMin) { #if DEBUG return scriptNameIncludingMin.Replace(".min", ""); // Remove .min from debug builds #else return scriptNameIncludingMin; #endif } // ... jsBundle.AddFile(Min("~/Scripts/jquery-1.7.2.min.js")); 

Essayez une nouvelle extension pour System.Web.Optimization – Bundle Transformer . Dans Bundle Transformer a mis en œuvre un certain nombre d'opportunités pour simplifier le débogage (voir la documentation ).

Une autre alternative (testée avec v1.1.0.0 et MVC5):

 public class BundleConfig { public static void Register() { ScriptBundle jsBundle = new ScriptBundle("~/Scripts/myscript.min.js"); jsBundle.Include("~/Scripts/myscript.js"); DisableInDebugMode(jsBundle); BundleTable.Bundles.Add(jsBundle); } private static void DisableInDebugMode(ScriptBundle jsBundle) { #if DEBUG // Don't minify in debug mode jsBundle.Transforms.Clear(); #endif } }