
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»