
Bundle Transformer – это разработанное мной модульное расширение для Microsoft ASP.NET Web Optimization Framework (другие названия: ASP.NET Bundling and Minification, System.Web.Optimization, Microsoft.Web.Optimization и ASP.NET Optimization – Bundling). В апреле этого года я уже делал подробный обзор возможностей Bundle Transformer, но за это время данный продукт очень сильно изменился. Поэтому я решил написать данный обзор и рассказать об основных изменениях, которые произошли в Bundle Transformer за прошедшие полгода.
Изменения, связанные с развитием Microsoft ASP.NET Web Optimization Framework
Апрельская версия Bundle Transformer была разработана для 1-й беты Microsoft ASP.NET Web Optimization Framework (далее B/M). Уже во 2-й бете B/M произошли серьезные изменения: сильно изменился API, появилась поддержка режима отладки и была признана устаревшей возможность создания динамических bundle`ов (больше не рекомендуется использовать метод
EnableDefaultBundles и класс DynamicFolderBundle). В финальной версии B/M уже не было кардинальных изменений, но добавилась одна очень полезная возможность – это поддержка CDN.Все перечисленные выше изменения также повлияли и на Bundle Transformer.
Начиная со 2-й беты B/M рекомендуется перенести код, создающий bundle`ы, из файла
Global.asax в класс BundleConfig и разместить этот класс в директории App_Start. В файле Global.asax нужно оставить только вызов метода RegisterBundles класса BundleConfig:using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace BundleTransformer.Example.Mvc { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); // Запускаем создание bundle`ов BundleConfig.RegisterBundles(BundleTable.Bundles); } } }
Рассмотрим создание bundle`ов и настройку их обработки с помощью Bundle Transformer на примере следующего класса
BundleConfig:using System.Web.Optimization; using BundleTransformer.Core.Orderers; using BundleTransformer.Core.Transformers; namespace BundleTransformer.Example.Mvc { public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { var cssTransformer = new CssTransformer(); var jsTransformer = new JsTransformer(); var nullOrderer = new NullOrderer(); var commonStylesBundle = new Bundle("~/Bundles/CommonStyles"); commonStylesBundle.Include( "~/Content/Site.css", "~/Content/BundleTransformer.css", "~/AlternativeContent/css/TestCssComponentsPaths.css", "~/Content/themes/base/jquery.ui.core.css", "~/Content/themes/base/jquery.ui.theme.css", "~/Content/themes/base/jquery.ui.resizable.css", "~/Content/themes/base/jquery.ui.button.css", "~/Content/themes/base/jquery.ui.dialog.css", "~/Content/TestTranslators.css", "~/Content/TestLess.less", "~/Content/TestSass.sass", "~/Content/TestScss.scss"); commonStylesBundle.Transforms.Add(cssTransformer); commonStylesBundle.Orderer = nullOrderer; bundles.Add(commonStylesBundle); var modernizrBundle = new Bundle("~/Bundles/Modernizr"); modernizrBundle.Include("~/Scripts/modernizr-2.*"); modernizrBundle.Transforms.Add(jsTransformer); modernizrBundle.Orderer = nullOrderer; bundles.Add(modernizrBundle); var commonScriptsBundle = new Bundle("~/Bundles/CommonScripts"); commonScriptsBundle.Include("~/Scripts/MicrosoftAjax.js", "~/Scripts/jquery-{version}.js", "~/Scripts/jquery-ui-{version}.js", "~/Scripts/jquery.validate.js", "~/Scripts/jquery.validate.unobtrusive.js", "~/Scripts/jquery.unobtrusive-ajax.js", "~/Scripts/knockout-2.*", "~/Scripts/TestCoffeeScript.coffee"); commonScriptsBundle.Transforms.Add(jsTransformer); commonScriptsBundle.Orderer = nullOrderer; bundles.Add(commonScriptsBundle); var jqueryUiStylesDirectoryBundle = new Bundle("~/Bundles/JqueryUiStylesDirectory"); jqueryUiStylesDirectoryBundle.IncludeDirectory("~/Content/themes/base/", "*.css"); jqueryUiStylesDirectoryBundle.Transforms.Add(new CssTransformer( new[] { "*.all.css", "jquery.ui.base.css" })); bundles.Add(jqueryUiStylesDirectoryBundle); var scriptsDirectoryBundle = new Bundle("~/Bundles/ScriptsDirectory"); scriptsDirectoryBundle.IncludeDirectory("~/Scripts/", "*.js"); scriptsDirectoryBundle.Transforms.Add(new JsTransformer( new[] { "*.all.js", "references.js" })); bundles.Add(scriptsDirectoryBundle); } } }
Главное отличие по сравнению с 1-й бетой B/M заключается в том, что для добавления файлов и директорий теперь используются методы
Include и IncludeDirectory (вместо методов AddFile и AddDirectory). Кроме того, добавление трансформаций теперь производится не через конструктор класса Bundle, а через его свойство Transforms (в приведенном выше коде вы можете увидеть это на примере добавления экземпляров классов CssTransformer и JsTransformer).Стоит отметить, что помимо классаBundleдля создания bundle`ов могут также использоваться его подклассыStyleBundle(для стилей) иScriptBundle(для скриптов). В эти классы уже добавлены трансформации, отвечающие за минимизацию кода (экземпляры классовCssMinifyиJsMinify). В нашем случае мы не можем использовать эти подклассы, потому что нам необходимо вместо экземпляров классовCssMinifyиJsMinifyдобавить трансформации из Bundle Transformer (экземпляры классовCssTransformerиJsTransformer).
Рассмотрим регистрацию ссылок на созданные bundlе`ы в коде представлений на примере файла
_Layout.cshtml:<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>@ViewBag.Title - Bundle Transformer Example MVC Application</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Bundles/CommonStyles") @Scripts.Render("~/Bundles/Modernizr") ... </head> <body> ... @Scripts.Render("~/Bundles/CommonScripts") @RenderSection("scripts", required: false) </body> </html>
Теперь ссылки на bundle`ы добавляются в код представления с помощью метода
Render (Styles.Render используется для CSS, а Scripts.Render для JavaScript). Использование метода Render не только делает добавление ссылок на bundle`ы более удобным, но и решает главную проблему ранних версий B/M – поддержку режима отладки.B/M определяет режим, в котором находится веб-приложение, на основе следующих настроек:
- Значения атрибута
debugэлементаcompilationиз файлаWeb.config(true– режим отладки;false– режим выпуска); - Значения свойства
BundleTable.EnableOptimizations, которое можно указать в классеBundleConfig(true– режим выпуска;false– режим отладки). Причем значение свойстваBundleTable.EnableOptimizationsимеет приоритет над настройками из файлаWeb.config.
В режиме выпуска код файлов, входящих в bundle, объединяется и обрабатывается (применяются трансформации). На выходе получается HTML-код следующего вида:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Home Page - Bundle Transformer Example MVC Application</title> <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> <link href="/Bundles/CommonStyles?v=IWN75r8IOIWnlehQ6JVPUgrb7UER075iobpzbjYTtRQ1" rel="stylesheet"/> <script src="/Bundles/Modernizr?v=1dm47T0PPFmcdy8ssp2EZ4h8yT2SjNhVvtdbc0MyDAs1"></script> ... </head> <body> ... <script src="/Bundles/CommonScripts?v=qWsyReB8UFAt-HPS-6MCkeDDTs2lQgYMdyCUd2V9O4o1"></script> </body> </html>
А в режиме отладки файлы, входящие в bundle, выводятся в исходном виде и по отдельности:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Home Page - Bundle Transformer Example MVC Application</title> <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> <link href="/Content/Site.css" rel="stylesheet"/> <link href="/Content/BundleTransformer.css" rel="stylesheet"/> <link href="/AlternativeContent/css/TestCssComponentsPaths.css" rel="stylesheet"/> <link href="/Content/themes/base/jquery.ui.core.css" rel="stylesheet"/> <link href="/Content/themes/base/jquery.ui.theme.css" rel="stylesheet"/> <link href="/Content/themes/base/jquery.ui.resizable.css" rel="stylesheet"/> <link href="/Content/themes/base/jquery.ui.button.css" rel="stylesheet"/> <link href="/Content/themes/base/jquery.ui.dialog.css" rel="stylesheet"/> <link href="/Content/TestTranslators.css" rel="stylesheet"/> <link href="/Content/TestLess.less" rel="stylesheet"/> <link href="/Content/TestSass.sass" rel="stylesheet"/> <link href="/Content/TestScss.scss" rel="stylesheet"/> <script src="/Scripts/modernizr-2.5.3.js"></script> ... </head> <body> ... <script src="/Scripts/MicrosoftAjax.debug.js"></script> <script src="/Scripts/jquery-1.8.1.js"></script> <script src="/Scripts/jquery-ui-1.8.23.js"></script> <script src="/Scripts/jquery.validate.js"></script> <script src="/Scripts/jquery.validate.unobtrusive.js"></script> <script src="/Scripts/jquery.unobtrusive-ajax.js"></script> <script src="/Scripts/knockout-2.1.0.debug.js"></script> <script src="/Scripts/TestCoffeeScript.coffee"></script> </body> </html>
Что существенно упрощает отладку клиентского кода.
Но если вы используете препроцессоры, то при работе в режиме отладки у вас могут возникнуть проблемы. В приведенном выше коде присутствуют ссылки на файлы с расширениями
.less, .sass, .scss и .coffee. Если в файле Web.config для этих расширений не зарегистрированы HTTP-хэндлеры, то содержимое этих файлов окажется необработанным и могут возникнуть ошибки на стороне клиента.Для решения данной проблемы в библиотеки трансляторов BundleTransformer.Less, BundleTransformer.LessLite, BundleTransformer.SassAndScss и BundleTransformer.CoffeeScript были добавлены реализации соответствующих HTTP-хэндлеров. При установке трансляторов через NuGet HTTP-хэндлеры регистрируются в файле
Web.config автоматически:<?xml version="1.0" encoding="utf-8"?> <configuration> ... <system.web> ... <httpHandlers> <!-- Declaration of Bundle Transformer HTTP-handlers --> <add path="*.less" verb="GET" type="BundleTransformer.LessLite.HttpHandlers.LessAssetHandler, BundleTransformer.LessLite" /> <add path="*.sass" verb="GET" type="BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler, BundleTransformer.SassAndScss" /> <add path="*.scss" verb="GET" type="BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler, BundleTransformer.SassAndScss" /> <add path="*.coffee" verb="GET" type="BundleTransformer.CoffeeScript.HttpHandlers.CoffeeScriptAssetHandler, BundleTransformer.CoffeeScript" /> <!-- /Declaration of Bundle Transformer HTTP-handlers --> </httpHandlers> </system.web> <system.webServer> ... <handlers> ... <!-- Declaration of Bundle Transformer HTTP-handlers --> <add name="LessAssetHandler" path="*.less" verb="GET" type="BundleTransformer.LessLite.HttpHandlers.LessAssetHandler, BundleTransformer.LessLite" resourceType="File" preCondition="" /> <add name="SassAssetHandler" path="*.sass" verb="GET" type="BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler, BundleTransformer.SassAndScss" resourceType="File" preCondition="" /> <add name="ScssAssetHandler" path="*.scss" verb="GET" type="BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler, BundleTransformer.SassAndScss" resourceType="File" preCondition="" /> <add name="CoffeeScriptAssetHandler" path="*.coffee" verb="GET" type="BundleTransformer.CoffeeScript.HttpHandlers.CoffeeScriptAssetHandler, BundleTransformer.CoffeeScript" resourceType="File" preCondition="" /> <!-- /Declaration of Bundle Transformer HTTP-handlers --> </handlers> </system.webServer> ... </configuration>
Исключение составляет лишь NuGet-пакет BundleTransformer.Less: при его установке также устанавливается пакет dotless, который автоматически регистрирует свою версию HTTP-хэндлера для обработки файлов с расширением
.less. Но у вас всегда есть возможность вручную заменить его на HTTP-хэндлер LessAssetHandler из BundleTransformer.Less.Управлять настройками родных HTTP-хэдлеров трансляторов можно с помощью конфигурационного элемента
/configuration/bundleTransformer/core/assetHandler из файла Web.config. В следующем коде показаны настройки HTTP-хэндлеров по умолчанию:<configuration> ... <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd"> <core> ... <assetHandler clientCacheDurationInDays="365" enableCompression="true" useLastModifiedHeader="true" useETagHeader="true" serverCacheDurationInMinutes="15" useServerCacheSlidingExpiration="false" disableClientCacheInDebugMode="true" disableCompressionInDebugMode="true" /> ... </core> </bundleTransformer> ... </configuration>
где,
clientCacheDurationInDays="(число)". Задает продолжительность нахождения текстового содержимого обработанного файла в кэше браузера (в днях).enableCompression="(true|false)". Включает GZIP/Deflate-сжатие обработанного файла.useLastModifiedHeader="(true|false)". Разрешает использовать HTTP-заголовокLast-Modifiedдля оповещения браузера об изменении обработанного файла.useETagHeader="(true|false)". Разрешает использовать HTTP-заголовокETagдля оповещения браузера об изменении обработанного файла.serverCacheDurationInMinutes="(число)". Задает продолжительность нахождения текстового содержимого обработанного файла в серверном кэше (в минутах).useServerCacheSlidingExpiration="(true|false)". Разрешает использование скользящего времени устаревания элемента серверного кэша.disableClientCacheInDebugMode="(true|false)". Отключает в режиме отладки браузерное кэширование обработанного файла.disableCompressionInDebugMode="(true|false)". Отключает в режиме отладки GZIP/Deflate-сжатие обработанного файла.
Трансляторы
Bundle Transformer: LESS Lite
В конце апреля появилась облегченная версия библиотеки dotless под названием DotlessClientOnly. Данная библиотека содержит только LESS-компилятор, а весь функционал, связанный с ASP.NET, из нее был удален (например, HTTP-хэндлер).
BundleTransformer.LessLite использует возможности DotlessClientOnly для трансляции LESS-кода в CSS. По возможностям и программному интерфейсу BundleTransformer.LessLite полностью эквивалентен BundleTransformer.Less. Поэтому если в ваших проектах вся работа с LESS производится только через Bundle Transformer, то лучше использовать модуль BundleTransformer.LessLite, т.к. в его основе лежит более легковесная библиотека.
Bundle Transformer: CoffeeScript
До версии 1.5.5 в BundleTransformer.CoffeeScript для трансляции CoffeeScript-кода в JavaScript использовалась библиотека SassAndCoffee.JavaScript версии 2.0.2.0. К сожалению, библиотека SassAndCoffee.JavaScript уже давно не развивается и поддерживает уже устаревшую версию CoffeeScript (версия 1.1.3). Поэтому в новых версиях BundleTransformer.CoffeeScript от нее пришлось отказаться и реализовать собственный компилятор, поддерживающий CoffeeScript 1.3.3.
Минимизаторы
Основной задачей при создании Bundle Transformer было предоставить разработчику возможность выбора из нескольких минимизаторов. В ранних версиях продукта разработчику были доступны адаптеры лишь для 2-х семейств минимизаторов: Microsoft Ajax Minifier и YUI Compressor. В текущей же версии доступны адаптеры практически для всех популярных минимизаторов CSS- и JS-кода.
Bundle Transformer: Closure
BundleTransformer.Closure содержит 2 минимизатора JS-кода:
ClosureRemoteJsMinifier и ClosureLocalJsMinifier. ClosureRemoteJsMinifier производит минимизацию с помощью веб-сервиса Google Closure Compiler Service API и требует постоянного подключения к Интернету. ClosureLocalJsMinifier осуществляет минимизацию средствами консольного приложения Google Closure Compiler Application, и требует для своей работы: виртуальную машину Java и последнюю версию файла compiler.jar.Bundle Transformer: JSMin
BundleTransformer.JsMin содержит адаптер-минимизатор JS-кода
CrockfordJsMinifier. CrockfordJsMinifier основан на C#-порте старейшего минимизатора JS-кода – JSMin, который был написан Дугласом Крокфордом (Douglas Crockford). Используемый C#-порт был создан на основе версии JSMin от 22 мая 2007 года.Bundle Transformer: UglifyJS
BundleTransformer.UglifyJs содержит адаптер-минимизатор JS-кода
UglifyJsMinifier. UglifyJsMinifier создан на основе популярного в сообществе Node.js минимизатора JS-кода — UglifyJS (сейчас поддерживается версия 1.3.3).Bundle Transformer: Packer
BundleTransformer.Packer содержит адаптер-минимизатор JS-кода
EdwardsJsMinifier. EdwardsJsMinifier создан на основе JS-минимизатора Дина Эдвардса (Dean Edwards) Packer версии 3.0. Главной особенностью Packer`а является то, что помимо минимизации и обфускации кода, он может еще производить сжатие кода с помощью алгоритма Base62. Base62-сжатие можно использовать, когда на веб-сервере отсутствует поддержка GZIP/Deflate-сжатия.Bundle Transformer: CSSO
BundleTransformer.Csso содержит адаптер-минимизатор CSS-кода
KryzhanovskyCssMinifier. KryzhanovskyCssMinifier основан на CSS-минимизаторе CSSO (сейчас поддерживается версия 1.2.18). Данный минимизатор был создан разработчиками методологии БЭМ: Сергеем Крыжановским и Виталием Харисовым. Главным отличием данного CSS-минимизатора от других средств минимизации CSS-кода — является поддержка структурной минимизации (например, с CSS-кодом производятся следующие операции: слияние блоков с одинаковыми селекторами, удаление перекрываемых свойств, частичное выделение свойств в отдельный блок, частичное слияние блоков и т.д.). Структурная минимизация дает высокую степень сжатия при минимизации кода сгенерированного «машиной» (например, препроцессором).Хочу отметить один важный момент: CSSO написан на ECMAScript 5 и я очень долго не мог найти JS-движок для .NET, который мог бы правильно выполнить код этой библиотеки. В итоге я остановил свой выбор на реализации JS-движка V8 под .NET — Noesis Javascript .NET. Данный движок частично написан на неуправляемом коде и имеет 2 версии: 32- и 64-разрядную. Из-за этой особенности реализации модуль BundleTransformer.Csso был разделен на 2 NuGet-пакета: BundleTransformer.Csso.x86 и BundleTransformer.Csso.x64. Для корректной работы Noesis Javascript .NET требуются сборки
msvcp100.dll и msvcr100.dll из Microsoft Visual C++ 2010. Если в вашей системе нет этих сборок, то рекомендую вам установить Microsoft Visual C++ 2010 Redistributable Package (x86, x64).Bundle Transformer: WebGrease
BundleTransformer.WG содержит адаптер-минимизатор CSS-кода
WgCssMinifier. WgCssMinifier производит минимизацию CSS-кода с помощью семантического CSS-минимизатора из разработанной Microsoft библиотеки WebGrease. Семантический CSS-минимизатор WebGrease также, как и CSSO производит структурную минимизацию CSS-кода.В данный момент, NuGet-пакет BundleTransformer.WG имеет статус альфа, т.к. текущая версия WebGrease (версия 1.1.0) содержит ошибку и из-за этого не может использоваться в производственных версиях сайтов.
Если вы хотите узнать больше о данном минимизаторе, то рекомендую вам посмотреть видео-доклад Говарда Дёркинга «Bundling and Optimizing».
Рекомендации по применению минимизаторов
Наиболее надежными минимизаторами являются минимизаторы из первой тройки: Microsoft Ajax Minifier, YUI Compressor и Google Closure Compiler (лидер по степени сжатия JS-кода). Все они обладают хорошей степенью сжатия, а обработанный ими код практически не содержит ошибок.
Новые минимизаторы, которые были разработаны под Node.js: UglifyJS и CSSO, дают более высокую степень сжатия, чем минимизаторы первой тройки (UglifyJS в некоторых случаях сжимает лучше, чем Google Closure Compiler в режиме
Simple), но пока еще не обладают таким уровнем надежности.Самые старые минимизаторы: JSMin и Packer, сейчас годятся только для сжатия самого простого JS-кода. К сожалению, они проигрывают современным минимизаторам и по степени сжатия, и по уровню надежности.
Я не сравнивал семантический минимизатор CSS-кода WebGrease с другими минимизаторами из-за специфики ошибки, содержащейся в нем. Но по общим наблюдениям, мне кажется, что он обладает большей степенью сжатия кода, чем CSSO.
Настройки
Текущие настройки Bundle Transformer эквивалентны следующему варианту файла
Web.config (в случае, когда установлены все дополнительные модули):<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- Declaration of Bundle Transformer configuration section group --> <sectionGroup name="bundleTransformer"> <section name="core" type="BundleTransformer.Core.Configuration.CoreSettings" /> <section name="less" type="BundleTransformer.LessLite.Configuration.LessLiteSettings" /> <section name="sassAndScss" type="BundleTransformer.SassAndScss.Configuration.SassAndScssSettings" /> <section name="microsoftAjax" type="BundleTransformer.MicrosoftAjax.Configuration.MicrosoftAjaxSettings" /> <section name="yui" type="BundleTransformer.Yui.Configuration.YuiSettings" /> <section name="closure" type="BundleTransformer.Closure.Configuration.ClosureSettings" /> <section name="uglify" type="BundleTransformer.UglifyJs.Configuration.UglifySettings" /> <section name="packer" type="BundleTransformer.Packer.Configuration.PackerSettings" /> <section name="csso" type="BundleTransformer.Csso.Configuration.CssoSettings" /> </sectionGroup> <!-- /Declaration of Bundle Transformer configuration section group --> ... </configSections> ... <!-- Bundle Transformer configuration settings --> <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd"> <core enableTracing="false" jsFilesWithMicrosoftStyleExtensions="MicrosoftAjax.js,MicrosoftMvcAjax.js, MicrosoftMvcValidation.js,knockout-$version$.js" useEnableOptimizationsProperty="true"> <css defaultMinifier="NullMinifier"> <minifiers> <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" /> <add name="MicrosoftAjaxCssMinifier" type="BundleTransformer.MicrosoftAjax.Minifiers.MicrosoftAjaxCssMinifier, BundleTransformer.MicrosoftAjax" /> <add name="YuiCssMinifier" type="BundleTransformer.Yui.Minifiers.YuiCssMinifier, BundleTransformer.Yui" /> <add name="KryzhanovskyCssMinifier" type="BundleTransformer.Csso.Minifiers.KryzhanovskyCssMinifier, BundleTransformer.Csso" /> <add name="WgCssMinifier" type="BundleTransformer.WG.Minifiers.WgCssMinifier, BundleTransformer.WG" /> </minifiers> <translators> <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" /> <add name="LessTranslator" type="BundleTransformer.LessLite.Translators.LessTranslator, BundleTransformer.LessLite" enabled="true" /> <add name="SassAndScssTranslator" type="BundleTransformer.SassAndScss.Translators.SassAndScssTranslator, BundleTransformer.SassAndScss" enabled="true" /> </translators> </css> <js defaultMinifier="NullMinifier"> <minifiers> <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" /> <add name="MicrosoftAjaxJsMinifier" type="BundleTransformer.MicrosoftAjax.Minifiers.MicrosoftAjaxJsMinifier, BundleTransformer.MicrosoftAjax" /> <add name="YuiJsMinifier" type="BundleTransformer.Yui.Minifiers.YuiJsMinifier, BundleTransformer.Yui" /> <add name="ClosureRemoteJsMinifier" type="BundleTransformer.Closure.Minifiers.ClosureRemoteJsMinifier, BundleTransformer.Closure" /> <add name="ClosureLocalJsMinifier" type="BundleTransformer.Closure.Minifiers.ClosureLocalJsMinifier, BundleTransformer.Closure" /> <add name="CrockfordJsMinifier" type="BundleTransformer.JsMin.Minifiers.CrockfordJsMinifier, BundleTransformer.JsMin" /> <add name="UglifyJsMinifier" type="BundleTransformer.UglifyJs.Minifiers.UglifyJsMinifier, BundleTransformer.UglifyJs" /> <add name="EdwardsJsMinifier" type="BundleTransformer.Packer.Minifiers.EdwardsJsMinifier, BundleTransformer.Packer" /> </minifiers> <translators> <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" /> <add name="CoffeeScriptTranslator" type="BundleTransformer.CoffeeScript.Translators.CoffeeScriptTranslator, BundleTransformer.CoffeeScript" enabled="true" /> </translators> </js> <assetHandler clientCacheDurationInDays="365" enableCompression="true" useLastModifiedHeader="true" useETagHeader="true" serverCacheDurationInMinutes="15" useServerCacheSlidingExpiration="false" disableClientCacheInDebugMode="true" disableCompressionInDebugMode="true" /> </core> <less useNativeMinification="false" severity="0" /> <sassAndScss useNativeMinification="false" /> <microsoftAjax> <css allowEmbeddedAspNetBlocks="false" colorNames="Strict" commentMode="Important" ignoreErrorList="" indentSize="4" minifyExpressions="true" outputMode="SingleLine" blocksStartOnSameLine="NewLine" preprocessorDefineList="" termSemicolons="false" severity="0" /> <js allowEmbeddedAspNetBlocks="false" collapseToLiteral="true" debugLookupList="Debug,$Debug,WAssert,Msn.Debug,Web.Debug" evalTreatment="Ignore" ignoreConditionalCompilation="false" ignoreErrorList="" indentSize="4" inlineSafeStrings="true" knownGlobalNamesList="" localRenaming="CrunchAll" macSafariQuirks="true" minifyCode="true" noAutoRenameList="$super" outputMode="SingleLine" blocksStartOnSameLine="NewLine" preprocessorDefineList="" preserveFunctionNames="false" preserveImportantComments="true" removeFunctionExpressionNames="true" removeUnneededCode="true" renamePairs="" strictMode="false" stripDebugStatements="true" termSemicolons="false" severity="0"/> </microsoftAjax> <yui> <css compressionType="Standard" removeComments="true" lineBreakPosition="-1" /> <js compressionType="Standard" obfuscateJavascript="true" preserveAllSemicolons="false" disableOptimizations="false" ignoreEval="false" severity="0" lineBreakPosition="-1" encoding="UTF8" threadCulture="en-us" /> </yui> <closure> <js> <remote closureCompilerServiceApiUrl="http://closure-compiler.appspot.com/compile" compilationLevel="Simple" prettyPrint="false" excludeDefaultExterns="false" severity="0" /> <local javaVirtualMachinePath="" closureCompilerApplicationPath="" compilationLevel="Simple" prettyPrint="false" languageSpec="EcmaScript3" thirdParty="true" processJqueryPrimitives="false" processClosurePrimitives="false" severity="0" /> </js> </closure> <uglify> <js> <parser strictSemicolons="false" /> <mangler mangle="true" topLevel="false" defines="" except="" noFunctions="false" /> <squeezer makeSequences="true" deadCode="true" unsafe="false" /> <codeGenerator beautify="false" indentStart="0" indentLevel="4" quoteKeys="false" spaceColon="false" asciiOnly="false" /> </js> </uglify> <packer> <js shrinkVariables="true" base62Encode="false" /> </packer> <csso> <css disableRestructuring="false" /> </csso> </bundleTransformer> <!-- /Bundle Transformer configuration settings --> ... </configuration>
В предыдущем обзоре я уже описывал структуру конфигурационной секции
bundleTransformer, поэтому на этот раз ограничусь лишь перечислением новых секций:closure– настройки модуля BundleTransformer.Closureuglify– настройки модуля BundleTransformer.UglifyJspacker– настройки модуля BundleTransformer.Packercsso– настройки модуля BundleTransformer.Csso
Названия и возможные значения свойств перечисленных выше конфигурационных секций также не нуждаются в пояснениях, т.к. практически полностью совпадают с конфигурационными свойствами исходных минимизаторов. Также напоминаю, что для конфигурационной секции
bundleTransformer реализована поддержка IntelliSense:
Заключение
В заключении я хотел бы отметить некоторые важные моменты, касающиеся B/M и Bundle Transformer.
Многие считают, что B/M может работать только с ASP.NET MVC, но это не так. Вы можете использовать B/M и в других ASP.NET-фреймворках: Web Forms и Web Pages (в разделе ссылки указаны статьи, в которых рассказывается, как это можно сделать).
Текущие версии B/M и Bundle Transformer написаны под .NET Framework 4.0, поэтому ничто не мешает вам использовать их в ASP.NET MVC 3 и ASP.NET Web Forms 4.0.
Ссылки
- Страница Bundle Transformer на CodePlex
- Страница Microsoft ASP.NET Web Optimization Framework на CodePlex
- Видео-доклад Говарда Дёркинга «Bundling and Optimizing»
- Видео-доклад Говарда Дёркинга «Build high-performing HTML 5 applications easily with ASP.NET 4.5»
- Учебник Рика Андерсона «Bundling and Minification»
- Статья Рика Андерсона «Adding Bundling and Minification to Web Forms» (перевод)
- Статья Рика Андерсона «Adding Web Optimization to a Web Pages Site» (перевод)
- Статья Говарда Дёркинга «Keeping in touch with the Web optimization team»

