A feature Bundles e Minification foi introduzida a partir da versão do ASP.NET MVC 4 e trouxe bastante praticidade, porém precisamos de um ajuste manual para obter a ordenação exata dos scripts.
Utilizar os Bundles da forma tradicional pode ocasionar alguns problemas na execução de nossos scripts devido ao seu padrão de ordenação. Encontrar a solução para estes problemas pode tomar algumas horas de trabalho se não observarmos corretamente o comportamento dos Bundles.
Um exemplo simples:
Para utilizar a biblioteca de globalização de validações “jquery.validate.globalize.js” certamente precisaremos da biblioteca “jquery.validate.js” e “globalize.js”, pois são dependências para que a validação funcione de forma globalizada. Portanto para o browser poder executar os métodos de “jquery.validate.globalize.js” é necessário ter carregado previamente a bibliotecas que são dependências.
Utilizando os Bundles de forma tradicional teríamos uma configuração parecida com o exemplo a seguir.
// Adicionando jQuery bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")); // Adicionando Validação, e Globalização bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate.js", "~/Scripts/globalize.js", "~/Scripts/jquery.validate.globalize.js"));
E por consequência o código HTML gerado para interpretação do browser não seria o esperado.
Uncaught ReferenceError: Globalize is not defined
Este problema ocorreu por que o Bundle não gerou os scripts na ordem em que foram declarados como no código acima, pois sua ordenação padrão não respeita a ordem da declaração. Logo a biblioteca “jquery.validate.globalize.js” não encontrou sua dependência e não executou suas funções.
Existem algumas formas de resolver este problema, minha recomendação é criar uma classe de ordenação que respeita a ordem em que as bibliotecas foram declaradas. Esta classe pode ser criada no próprio arquivo “BundleConfig.cs” para manter a simplicidade da implementação.
public class AsIsBundleOrderer : IBundleOrderer { public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files) { return files; } }
E a forma de declaração do Bundle precisa ser modificada para fazer uso desta nova ordenação.
// Adicionando jQuery bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")); // Adicionando Validação, e Globalização // Utilizando ordenação manual var valBundle = new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate.js", "~/Scripts/globalize.js", "~/Scripts/jquery.validate.globalize.js"); valBundle.Orderer = new AsIsBundleOrderer(); bundles.Add(valBundle);
Utilizamos algumas linhas a mais, porém garantimos a ordenação da forma que o browser precisa para poder executar tudo corretamente. O resultado é como o esperado.
Como podemos conferir é muito importante estar atento a este comportamento dos Bundles para evitar possíveis problemas e por consequência perder um tempo precioso de trabalho.
* Esta abordagem vale também para os StyleBundles que trabalham com CSS.
** Caso esteja trabalhando com o recurso de Minification este comportamento pode ocorrer ou não dependendo do cenário.
Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:
Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis.