Como desativar a minificação de Javascript / CSS na ASP.NET MVC 4 Beta
-
28-10-2019 - |
Pergunta
Estou apenas experimentando a ASP.NET MVC 4, mas não consigo descobrir como desabilitar o recurso de minificação Javascript / CSS.Especialmente para o ambiente de desenvolvimento, isso ajudará muito na depuração.Eu imagino que seria uma mudança no web.config, mas como a ASP.NET MVC 4 ainda está em estágio beta no momento, não há muita informação por aí.Agradeceria se alguém pudesse ajudar ou apontar para as postagens certas do blog, etc.
Solução
Em Global.asax.cs
#if DEBUG
foreach (var bundle in BundleTable.Bundles)
{
bundle.Transform = new NoTransform();
}
#endif
Outras dicas
Outra opção seria criar um HTML Helper que você pudesse usar para construir o script e vincular as tags.Aqui está o que eu implementei para o Javascript, o que também pode ser feito para o 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());
}
}
Agora, tudo o que você precisa fazer é colocá-lo em seu ponto de vista:
<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>
E irá renderizar os scripts como referências separadas, ou usar o novo recurso de agrupamento / minificação, dependendo de qual configuração de depuração está em seu web.config.Usei parte do código de http://codecutout.com/resource-minify-bundling comouma referência ao criar meu ajudante se você quiser ver mais alguns exemplos.Seu ajudante é escrito um pouco melhor, lançando exceções quando argumentos inválidos são fornecidos, etc ... Eu só não consegui limpar o meu ainda.
Você pode registrar seus próprios pacotes no Global.asax e usar a classe NoTransform
se não quiser que o conteúdo seja reduzido.
Eu pessoalmente não quero que meu script seja transformado de forma alguma.Acabei de criar dois diretórios de script.Um com as versões do script de depuração e outro com as versões reduzidas originalmente baixadas.
O minificador pronto para uso MVC 4 (JsMinify) quebra o jQuery 1.7.1 para Opera, então não quero usá-lo.Acabei de colocar as seguintes linhas no meu Global.asax : método 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);
Com isso no lugar, posso simplesmente adicionar uma das duas linhas em meu _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>
É claro que poderíamos ficar um pouco mais descolados com isso.Poderíamos gerar apenas um pacote e, dependendo do tipo de construção, selecionar quais arquivos incluir.
Após a chamada para EnableDefaultBundles()
em Global.asax, você pode fazer isso ...
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();
}
}
Não é bonito (modificando o estado definido pelo sistema), mas é muito menos código do que todas as outras sugestões, ainda permite que você use o comportamento de empacotamento padrão e não envolve nenhuma mudança em suas visualizações.
Em versões mais recentes da ASP.NET MVC, basta adicionar
#if DEBUG
foreach (var bundle in BundleTable.Bundles)
{
bundle.Transforms.Clear();
}
#endif
logo depois
BundleConfig.RegisterBundles(...);
você pode desligá-lo na configuração:
<system.web>
<compilation debug="true" />
<!-- Lines removed for clarity. -->
</system.web>
http://www.asp.net/mvc/tutorials / mvc-4 / bundling-and-minification
Acho que seria correto se esse recurso estivesse disponível "fora da caixa".
Eu postei um feedback no UserVoice.com: http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/2702000-improve-system-web-optimization-bundle
Dê a sua "voz".
Em vez de substituir instâncias de JsMinify e CssMinify, pode-se usar interfaces. Esta opção não estava disponível em versões anteriores porque o segundo parâmetro do construtor era um tipo em vez de uma 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);
Talvez também seja digno de nota, para scripts que são enviados com versões reduzidas e não reduzidas, por exemplo,jQuery, pode-se usar um método auxiliar para opcionalmente remover o ".min" para compilações DEBUG para facilitar a depuração:
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"));
Experimente uma nova extensão para System.Web.Optimization - Bundle Transformer .No Bundle Transformer implementou uma série de oportunidades para simplificar a depuração (consulte documentação ).
Outra alternativa (testado com v1.1.0.0 e 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
}
}