Не даем бандлам испортить вам жизнь

88acade3b3431ffd0983d865fd70124f.jpgНедавно столкнулся с проблемой конфликта бандлов в MVC проекте, случалось так, что некоторые скрипты оказывались по нескольку раз подключенными в разных бандлах. Вычленение какого-то лишнего скрипта из одного из них может привести к серьезной головной боли, ведь один и то же бандл может использоваться на разных лейаутах.Я видел разные способы группировки скриптов, но, честно говоря, ни один из них мне до конца не нравился. Как все-таки группировать скрипты так, чтобы было сложнее всего в них запутаться и не приходилось бы заморачиваться по поводу конфликтов разных бандлов на одной странице? Для себя я придумал подход, который, на мой взгляд, упросит жизнь. Очень буду рад здоровой критике и полезным советам.

Начнем с того, что попробуем проанализировать парочку подходов для группировки скриптов: Первый подход — объединение в группы по общему назначению скриптов.

bundles.Add (new ScriptBundle (»~/bundles/jquery»).Include ( »~/Scripts/jquery-{version}.js»));

bundles.Add (new ScriptBundle (»~/bundles/jqueryui»).Include ( »~/Scripts/jquery-ui-{version}.js»));

bundles.Add (new ScriptBundle (»~/bundles/jqueryval»).Include ( »~/Scripts/jquery.unobtrusive*», »~/Scripts/jquery.validate*»)); Достаточно просто и проблем быть не должно, но этого подхода не достаточно. Кастомные скрипты тоже как-то нужно сгруппировать. Здесь и возникает второй подход — объединение скриптов в какой-то базовый бандл.

bundles.Add (new ScriptBundle (»~/Scripts/base»).Include ( »~/Scripts/placeholder.js», »~/Scripts/modernizr-*», »~/Scripts/my-custom-script-1», »~/Scripts/my-custom-script-2)); И тут же возникает вопрос что сюда включать. Jquery вроде базовый скрипт, но для него у нас уже есть отдельный бандл. Такая же история может случиться и с любым другим скриптом, который один из разработчиков в большой команде посчитает, что его нужно туда включить. Таким образом чем больше мнений — тем больше неожиданных проблем с группировкой скриптов.

Я для себя выбрал следующий путь:1. На каждый лэйаут — 1 бандл.Называю бандл таким же именем, как и сам лэйаут и решаю головную боль с тем, что подключать, куда подключать и сколько подключать.

2. Бандлы подключаются только на лэйаутах.В итоге: сколько лэйаутов — столько и одноименных бандлов.

Если здесь у вас возникла буря негодований, то попридержите их до конца пути, когда сложится целостная картина.

3. Вводим понятие групп, которое будет являться просто массивом строк.В группу объединяем все необходимые скрипты для какого-то конкретного функционала. Вот пример группы скриптов для рендеринга отчетов с графиками на svg холстах:

var reportScriptGroup = new[] { »~/Scripts/jquery-{version}.js», »~/Scripts/raphael.js», »~/Scripts/Custom/charts.js», »~/Scripts/Custom/report.js» }; Предположим, что в этом же лэйауте вам необходима клиентская валидация, добавляем группу для валидации:

var validationScriptGroup = new[] { »~/Scripts/jquery-{version}.js», »~/Scripts/jquery.validate.js», »~/Scripts/jquery.validate.unobtrusive.js», »~/Scripts/Custom/jquery.custom.validate.js» }; Обратите внимание на наличие jquery-{version}.js в обоих группах, но это нам не мешает добавить обе группы в один и тот же бандл. Он сам позаботится о том, чтобы сделать дистинкт.

bundles.Add (new ScriptBundle (»~/Scripts/_DashboardLayout») .Include (baseScriptGroup) .Include (validationScriptGroup) .Include (reportScriptGroup) ) ); 4. Мне также понадобилось исключить скрипт из группы, чтобы не создавать новую.Например, скрипт, который показывает страницу постепенно ее разблюривая. Он находится в группе baseScriptGroup. Мне он совершенно не нужен на лэйауте для подготовки всякого добра к печати или конвертации в pdf и т.п.

Напишем нехитрый метод для исключения скрипта из группы:

private static string[] Exclude (this IEnumerable input, params string[] items) { var output = input; foreach (var item in items) { output = output.Where (x => x!= item).ToArray (); }

return output.ToArray (); } А бандл для него будет выглядеть вот так:

bundles.Add (new ScriptBundle (»~/Scripts/_PrintLayout») .Include (baseScriptGroup.Exclude (»~/Scripts/Custom/fading.js»)) .Include (reportScriptGroup) ) ); Вот и все. Таким образом можно просто объединять группы в бандл. Захотелось подключить графики — добавил в бандл группу с графиками. Захотел валидацию — добавь и ее.

© Habrahabr.ru