Переходимо на WebMarkupMin 2.X

Логотипи WebMarkupMin, .NET Core і NUglify
Навесні минулого року, коли ASP.NET 5 був ще в стадії Beta 3, я почав отримувати від користувачів листи з проханнями зробити WebMarkupMin сумісним з DNX 4.5.1 та DNX Core 5.0. Основною проблемою було те, що новий .NET не підтримував налаштування за допомогою конфігураційних файлів
App.config
та
Веб.config
. Переписування WebMarkupMin.Core, WebMarkupMin.MsAjax і WebMarkupMin.Yui не повинно було представляти особливої складності, тому що потрібно було просто видалити весь код, що використовує бібліотеку
System.Configuration
. Серйозні проблеми повинні були виникнути при переписуванні ASP.NET-розширень, тому що для них потрібно було розробити абсолютно нову модель конфігурації, а це, в свою чергу, вимагало дуже серйозних змін в архітектурі. Ці зміни торкалися не тільки код, але і структуру рішення і NuGet-пакети, тому я вирішив почати з чистого аркуша і зробив репозиторій на GitHub. На той момент, до релізу стабільної версії нового ASP.NET залишалося як мінімум півроку, тому потрібно було одночасно підтримувати 2 гілки WebMarkupMin: стабільну 1.X CodePlex і попередню 2.X на GitHub.


Як відомо всім, вихід стабільних версій .NET і ASP.NET Core 1.0 затримався ще на кілька місяців і відбувся лише в кінці червня цього року. Слідом за релізом цих фреймворків, відбувся і реліз WebMarkupMin 2.0. У цій статті я розповім вам про те, як оновити існуючі програми під WebMarkupMin 2.X, а також як додати його в веб-додатки, написані на ASP.NET Core.

Критичні зміни і нововведення
Для того щоб встановити пакети WebMarkupMin 2.X вам необхідно оновити NuGet Package Manager до версії 2.8.6 або вище.

Основним критичним зміною версії 2.X стала відмова від використання файлів
Веб.config
та
App.config
для налаштування WebMarkupMin. Тепер при налаштуванні замість декларативного підходу (використання конфігураційних файлів) використовується імперативний підхід (використання програмного коду).

Тому при оновленні WebMarkupMin до версії 2.X потрібно обов'язково зробити 2 речі:

  1. Видалити пакет WebMarkupMin.ConfigurationIntelliSense, т. к. в ньому більше немає необхідності.
  2. Після видалення застарілих пакетів і оновлення старих версій пакетів до нових, необхідно видалити групу конфігураційних секцій
    webMarkupMin
    та її оголошення з файлів
    Веб.config
    та
    App.config
    :

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <configSections>
    …
    <sectionGroup name="webMarkupMin">
    …
    </sectionGroup>
    …
    </configSections>
    …
    <webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
    …
    </webMarkupMin>
    …
    </configuration>
Далі розглянемо процедуру оновлення для кожного пакету окремо.

Core
Після оновлення пакета WebMarkupMin.Core потрібно в коді програми замінити всі підключення просторів імен
WebMarkupMin.Core.Minifiers
та
WebMarkupMin.Core.Settings
на
WebMarkupMin.Core
.

Зовнішні минификаторы CSS і JS-коду
На жаль, модулі WebMarkupMin.MsAjax і WebMarkupMin.Yui не підтримують .NET Core, і тому можуть використовуватися тільки в додатках .NET 4.X, веб-додатках ASP.NET 4.X і веб-додатках ASP.NET Core, створених на основі шаблону «ASP.NET Core Web Application (.NET Framework)». Це викликано тим, що автори Microsoft Ajax Minifier і YUI Compressor for .NET не портували свої бібліотеки під .NET Core. Про YUI Compressor for .NET не можу сказати нічого певного, можливо через якийсь час його все-таки портируют. Щодо Microsoft Ajax Minifier вже все гранично ясно: його розробка була припинена у березні 2015 року (після відходу Рона Логана з Microsoft). Але не все так погано, тому що існує «форк» Microsoft Ajax Minifier під назвою NUglify, який сумісний з .NET Core. У новій версії WebMarkupMin є пакет, заснований на ньому — WebMarkupMin.NUglify.

MS Ajax

Після оновлення пакета WebMarkupMin.MsAjax потрібно в коді програми замінити всі підключення просторів імен
WebMarkupMin.MsAjax.Minifiers
та
WebMarkupMin.MsAjax.Settings
на
WebMarkupMin.MsAjax
.

YUI

Після оновлення пакета WebMarkupMin.Yui потрібно в коді програми замінити всі підключення просторів імен
WebMarkupMin.Yui.Minifiers
та
WebMarkupMin.Yui.Settings
на
WebMarkupMin.Yui
.

NUglify

На даний момент, API WebMarkupMin.NUglify повністю ідентичний WebMarkupMin.MsAjax. Тому при переході з WebMarkupMin.MsAjax на WebMarkupMin.NUglify в коді додатка досить просто замінити префікси
MsAjax
на
NUglify
.

Розширення для інтеграції з ASP.NET
Всі пакети з ASP.NET-розширеннями для версії 1.XWebMarkupMin.Web, WebMarkupMin.Mvc і WebMarkupMin.WebForms) визнані застарілими і не використовуються в WebMarkupMin 2.X.

Перерахую основні нововведення у розширення для ASP.NET:

  1. Перехід на імперативний підхід до налагодження розширень.
  2. Тепер можна асоціювати типи вмісту MIME-типи) з відповідними минификаторами розмітки.
  3. З'явилася можливість вказувати минификатору які сторінки сайту він повинен обробити.


ASP.NET 4.X HTTP modules

Щоб оновити веб-додаток ASP.NET, яке використовує HTTP-модулі з пакету WebMarkupMin.Web потрібно виконати наступні дії:

  1. Видалити пакет WebMarkupMin.Web.
  2. Встановити пакет WebMarkupMin.AspNet4.HttpModules.
  3. Оновити залишилися старі пакети WebMarkupMin до версії 2.X.
  4. У файлі
    Веб.config
    потрібно замінити: простір імен
    WebMarkupMin.Web.HttpModules
    на
    WebMarkupMin.AspNet4.HttpModules
    , ім'я складання
    WebMarkupMin.Web
    на
    WebMarkupMin.AspNet4.HttpModules
    і ім'я класу
    CompressionModule
    на
    HttpCompressionModule
    .
Завдяки появі можливості вказувати минификатору які сторінки сайту він повинен обробити, HTTP-модулі
HtmlMinificationModule
та
XhtmlMinificationModule
можуть використовуватися разом.

ASP.NET 4.X MVC

Щоб оновити веб-додаток ASP.NET MVC, яке використовує фільтри дій з пакету WebMarkupMin.Mvc потрібно виконати наступні дії:

  1. Видалити пакети WebMarkupMin.Mvc і WebMarkupMin.Web.
  2. Встановити пакет WebMarkupMin.AspNet4.Mvc.
  3. Оновити залишилися старі пакети WebMarkupMin до версії 2.X.
  4. У коді програми замінити всі підключення простору імен
    WebMarkupMin.Mvc.ActionFilters
    на
    WebMarkupMin.AspNet4.Mvc
    .
Варто також зазначити, що на відміну від старих версій WebMarkupMin, у версії 2.X ви можете застосовувати фільтри дій до контролерів:

…
using System.Web.Mvc;

using WebMarkupMin.AspNet4.Mvc;
…

namespace WebMarkupMin.Sample.AspNet4.Mvc4.Controllers
{
[CompressContent]
[MinifyHtml]
[MinifyXhtml]
[MinifyXml]
…
public class HomeController : Controller
{
…
}
} 

Крім того, у версії 2.X можна застосовувати фільтри дій на рівні всього веб-додатки. Для цього потрібно відредагувати файл
App_Start/FilterConfig.cs
наступним чином:

using System.Web.Mvc;

using WebMarkupMin.AspNet4.Mvc;

namespace WebMarkupMin.Sample.AspNet4.Mvc4
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
…
filters.Add(new CompressContentAttribute());
filters.Add(new MinifyHtmlAttribute());
filters.Add(new MinifyXhtmlAttribute());
filters.Add(new MinifyXmlAttribute());
…
}
}
}

Також у минуле пішли помилки виду «The 'MinifyXXXAttribute' attribute can not be applied to the 'XXX' action method of the 'XXX' controller, because it returns the result with not supported content type.». Тепер, якщо тип вмісту результату дії не відповідає фільтру, то до цього результату просто не застосовується минификация.

ASP.NET 4.X Web Forms

Щоб оновити веб-додаток ASP.NET Web Forms, яке використовує класи сторінок або майстер-сторінок з пакету WebMarkupMin.WebForms потрібно виконати наступні дії:

  1. Видалити пакети WebMarkupMin.WebForms і WebMarkupMin.Web.
  2. Встановити пакет WebMarkupMin.AspNet4.WebForms.
  3. Оновити залишилися старі пакети WebMarkupMin до версії 2.X.
  4. У коді програми замінити всі підключення просторів імен
    WebMarkupMin.WebForms.Pages
    та
    WebMarkupMin.WebForms.MasterPages
    на
    WebMarkupMin.AspNet4.WebForms
    .
У версії 2.X були додані класи сторінки, які підтримують тільки минификацию (без HTTP-стиснення):
MinifiedHtmlPage
та
MinifiedXhtmlPage
. Також відповідні класи з'явилися і для майстер-сторінок:
MinifiedHtmlMasterPage
та
MinifiedXhtmlMasterPage
.

ASP.NET Core 1.X

У новій версії WebMarkupMin з'явилося розширення для ASP.NET Core — пакет WebMarkupMin.AspNetCore1. По функціоналу цей пакет нагадує WebMarkupMin.AspNet4.HttpModules, тільки замість чотирьох HTTP-модулів тут міститься один компонент middleware. Головною відмінністю цього пакету від WebMarkupMin.AspNet4.HttpModules є підключення модулів (можливостей) і їх налаштування здійснюються в одному місці – у файлі
Startup.cs
.

Розглянемо приклад підключення модулів:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using WebMarkupMin.AspNetCore1;

namespace TestAspNetCore1
{
public class Startup
{
…
// This method gets called by the runtime.
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
…
// Add WebMarkupMin services.
services.AddWebMarkupMin()
.AddHtmlMinification()
.AddXmlMinification()
.AddHttpCompression()
;

// Add services framework.
services.AddMvc();
}

// This method gets called by the runtime.
// Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
…
app.UseWebMarkupMin();

app.UseMvc(routes =>
{
…
});
}
}
}

У методі
ConfigureServices
провадиться реєстрація сервісів. За допомогою методу-розширення
AddWebMarkupMin
та його дочірніх методів (
AddHtmlMinification
,
AddXmlMinification
та
AddHttpCompression
) ми додаємо сервіси WebMarkupMin в контейнер впровадження залежностей:

  1. Метод
    AddWebMarkupMin
    реєструє такі класи як сінглтон:
    ThrowExceptionLogger
    (реалізація інтерфейсу
    ILogger
    ),
    KristensenCssMinifierFactory
    (реалізація інтерфейсу
    ICssMinifierFactory
    )
    CrockfordJsMinifierFactory
    (реалізація інтерфейсу
    IJsMinifierFactory
    ). Сам по собі цей метод не підключає ні одного модуля (можливості), для цієї мети служать його дочірні методи. Наприклад, якщо не викликати метод
    AddHtmlMinification
    , то HTML-минификация буде недоступна.
  2. Метод
    AddHtmlMinification
    реєструє клас
    HtmlMinificationManager
    (реалізація інтерфейсу
    IHtmlMinificationManager
    ) як сінглтона. Також існує аналогічний метод —
    AddXhtmlMinification
    , який реєструє клас
    XhtmlMinificationManager
    як реалізацію інтерфейсу
    IXhtmlMinificationManager
    .
  3. Метод
    AddXmlMinification
    реєструє клас
    XmlMinificationManager
    (реалізація інтерфейсу
    IXmlMinificationManager
    ) як сінглтона.
  4. Метод
    AddHttpCompression
    реєструє клас
    HttpCompressionManager
    (реалізація інтерфейсу
    IHttpCompressionManager
    ) у вигляді сінглтона.
У методі
Configure
провадиться реєстрація компонентів middleware. За допомогою методу-розширення
UseWebMarkupMin
ми додаємо клас
WebMarkupMinMiddleware
в конвеєр ASP.NET. Виклик цього методу повинен бути зроблений безпосередньо перед викликом методу
UseMvc
, тому що компонент
RouterMiddleware
завершує ланцюжок викликів.

Таким чином, ми додали в наш веб-додаток HTML-минификацию, XML-минификацию і HTTP-стиснення. В розділі «Модель конфігурації ASP.NET Core-розширення» ми розглянемо, як налаштувати і змінити додані сервіси.

Базова модель конфігурації ASP.NET-розширень
До WebMarkupMin 2.X налаштування ASP.NET-розширень проводилася шляхом редагування файлу
Веб.config
. Зараз для розширень замість декларативного підходу (використання конфігураційного файлу) використовується імперативний підхід (використання програмного коду).

Відмова від декларативного підходу був викликаний наступними причинами:

  1. Microsoft вже кілька років, використовує імперативний підхід для налаштування окремих частин ASP.NET (наприклад, Web API або Web Optimization Framework).
  2. ASP.NET Core залишилася лише обмежена підтримка файлів
    Веб.config
    (в основному для інтеграції з IIS).
Розширення для ASP.NET 4.X і ASP.NET Core 1.X використовують різні конфігураційні моделі. В ASP.NET 4.X налагодження розширень виробляється через спеціальні класи:
WebMarkupMinConfiguration
,
HtmlMinificationManager
,
XhtmlMinificationManager
та
XmlMinificationManager
. В ASP.NET Core 1.X налагодження розширень базується на фреймворку Microsoft.Extensions.Options і використовує наступні класи:
WebMarkupMinOptions
,
HtmlMinificationOptions
,
XhtmlMinificationOptions
та
XmlMinificationOptions
. Однак ці моделі конфігурації мають багато спільного, а їхні інтерфейси і базові класи виділені в окремий пакет — WebMarkupMin.AspNet.Common.

Базові налаштування ASP.NET-розширень
Класи
WebMarkupMinConfiguration
та
WebMarkupMinOptions
успадковують клас
WebMarkupMinConfigurationBase
, який має наступні властивості.







Властивість Тип даних Значення за замовчуванням Опис
DisableMinification
Булевский
false
Вимикає минификацию розмітки.
DisableCompression
Булевский
false
Вимикає HTTP-стиснення текстового контенту.
MaxResponseSize
Ціле число
-1
Максимальний розмір для HTTP-відповіді (в байтах), при перевищенні якого вимикається минификация розмітки. Якщо значення властивості дорівнює
-1
, то перевірка розміру HTTP-відповіді не проводиться.
DisablePoweredByHttpHeaders
Булевский
false
Вимикає HTTP-заголовки
*-Minification-Powered By
(наприклад, заголовок
X-HTML-Minification-Powered By: WebMarkupMin
)
Цей клас і його підкласи є заміною конфігураційної секції
configuration/webMarkupMin/webExtensions
з попередньої версії WebMarkupMin.

Менеджери та опції минификации розмітки
Менеджери минификации по своїй суті є налаштованим фабриками, які створюють примірники минификаторов розмітки. Але крім цього вони ще містять логіку, що дозволяє вибірково застосовувати минификацию (на основі типу вмісту та URL).

Всі класи менеджерів і опцій минификации розмітки мають властивості
IncludedPages
та
ExcludedPages
, які дозволяють включати/виключати сторінки сайту з процесу обробки минификатором. Ці властивості мають тип
IList<IUrlMatcher>
, і за замовчуванням містять порожні списки, т. к. за замовчуванням фільтрація відключена і минифицируются всі сторінки.

Існує 3 вбудованих реалізації інтерфейсу
IUrlMatcher
:

  1. ExactUrlMatcher
    . В якості шаблону використовується URL (наприклад,
    new ExactUrlMatcher("/contact")
    ).
  2. RegexUrlMatcher
    . В якості шаблону використовується регулярний вираз, сумісний зі стандартом ECMAScript (наприклад,
    new RegexUrlMatcher(@"^/minifiers/x(?:ht)?ml-minifier$")
    ).
  3. WildcardUrlMatcher
    . Використовується шаблон, підтримує синтаксис Wildcard (наприклад,
    new WildcardUrlMatcher("/minifiers/x*ml-minifier")
    ). Цей синтаксис підтримує 2 метасимвола: зірочку (
    *
    ) — відповідає рядку символів, навіть порожній; і знак питання (
    ?
    ) — відповідає будь-якому окремому символу.
За замовчуванням усі вищеперелічені реалізації інтерфейсу
IUrlMatcher
не чутливі до регістру. Щоб змінити цю поведінку потрібно передати в конструктор класу в якості другого параметра значення рівне
true
(наприклад,
new ExactUrlMatcher("/Contact", true)
).

Менеджер і опції HTML минификации

Класи
HtmlMinificationManager
та
HtmlMinificationOptions
мають такі загальні властивості:









Властивість Тип даних Значення за замовчуванням Опис
MinificationSettings
HtmlMinificationSettings
Екземпляр класу
HtmlMinificationSettings
Настройки HTML-минификатора.
SupportedMediaTypes
ISet<string>
text/html
Список підтримуваних типів вмісту.
IncludedPages
IList<IUrlMatcher>
Порожній список Включає сторінки сайту в процес обробки HTML-минификатором.
ExcludedPages
IList<IUrlMatcher>
Порожній список Виключає сторінки сайту з процесу обробки HTML-минификатором.
CssMinifierFactory
ICssMinifierFactory
Екземпляр класу
KristensenCssMinifierFactory
Фабрика CSS-минификаторов.
JsMinifierFactory
IJsMinifierFactory
Екземпляр класу
CrockfordJsMinifierFactory
Фабрика JS-минификаторов.

Менеджер і опції XHTML минификации

Класи
XhtmlMinificationManager
та
XhtmlMinificationOptions
мають такі загальні властивості:









Властивість Тип даних Значення за замовчуванням Опис
MinificationSettings
XhtmlMinificationSettings
Екземпляр класу
XhtmlMinificationSettings
Налаштування XHTML-минификатора.
SupportedMediaTypes
ISet<string>
text/html
,
application/xhtml+xml
Список підтримуваних типів вмісту.
IncludedPages
IList<IUrlMatcher>
Порожній список Включає сторінки сайту в процес обробки XHTML-минификатором.
ExcludedPages
IList<IUrlMatcher>
Порожній список Виключає сторінки сайту з процесу обробки XHTML-минификатором.
CssMinifierFactory
ICssMinifierFactory
Екземпляр класу
KristensenCssMinifierFactory
Фабрика CSS-минификаторов.
JsMinifierFactory
IJsMinifierFactory
Екземпляр класу
CrockfordJsMinifierFactory
Фабрика JS-минификаторов.

Менеджер і опції XML минификации

Класи
XmlMinificationManager
та
XmlMinificationOptions
мають такі загальні властивості:







Властивість Тип даних Значення за замовчуванням Опис
MinificationSettings
XmlMinificationSettings
Екземпляр класу
XmlMinificationSettings
Налаштування XML-минификатора.
SupportedMediaTypes
ISet<string>
application/xml
,
text/xml
,
application/xml dtd
,
application/xslt+xml
,
application/rss+xml
,
application/atom+xml
,
application/rdf+xml
,
application/soap+xml
,
application/wsdl+xml
,
image/svg+xml
,
application/mathml+xml
,
application/voicexml+xml
,
application/srgs+xml
Список підтримуваних типів вмісту.
IncludedPages
IList<IUrlMatcher>
Порожній список Включає сторінки сайту в процес обробки XML-минификатором.
ExcludedPages
IList<IUrlMatcher>
Порожній список Виключає сторінки сайту з процесу обробки XML-минификатором.
Менеджер HTTP стиснення
Клас
HttpCompressionManager
теж є фабрикою і відповідає за створення примірників GZip — і Deflate-компресорів. Але на відміну від менеджерів минификации він не має загальних властивостей. Також, як і менеджери минификации, він містить логіку, яка дозволяє застосовувати HTTP-стиснення вибірково (стискається тільки текстове вміст).

Рішення про те, який тип компресора потрібно створити приймається на основі значення HTTP-заголовка
Accept-Encoding
. Якщо браузер підтримує обидва типи стиснення, то перевага віддається Deflate.

Модель конфігурації ASP.NET 4.X-розширень
Налаштування ASP.NET 4.X-розширень виробляється через спеціальні класи:
WebMarkupMinConfiguration
,
HtmlMinificationManager
,
XhtmlMinificationManager
та
XmlMinificationManager
(ці класи визначені в пакеті WebMarkupMin.AspNet4.Common).

Налаштування ASP.NET-розширення
Клас
WebMarkupMinConfiguration
на додаток до властивостей, наслідуваних від класу
WebMarkupMinConfigurationBase
, також має свої власні властивості:





Властивість Тип даних Значення за замовчуванням Опис
AllowMinificationInDebugMode
Булевский
false
Дозволяє минификацию розмітки в режимі налагодження.
AllowCompressionInDebugMode
Булевский
false
Дозволяє HTTP-стиснення текстового вмісту в режимі налагодження.
Режим налагодження визначається на основі значення атрибута
debug
конфігураційного елемента
configuration/system.web/compilation
з файлу
Веб.config
:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
…
<system.web>
…
<compilation debug="false" … />
…
</system.web>
…
</configuration>

За замовчуванням у режимі відладки не проводитися минификация і HTTP-стиснення. Щоб включити їх потрібно присвоїти перерахованим вище конфігураційним властивостям значення рівне
true
або перекласти веб-додатки в режим релізу.

Особливості налаштування
Перш ніж розповісти про особливості розширень для ASP.NET 4.X в WebMarkupMin версії 2.X, я спочатку наведу приклад налаштувань на основі файлу
Веб.config
з попередньої версії:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
…
<sectionGroup name="webMarkupMin">
<section name="core"
type="WebMarkupMin.Core.Configuration.CoreConfiguration, WebMarkupMin.Core" />
<section name="msAjax"
type="WebMarkupMin.MsAjax.Configuration.MsAjaxConfiguration, WebMarkupMin.MsAjax" />
<section name="webExtensions"
type="WebMarkupMin.Web.Configuration.WebExtensionsConfiguration, WebMarkupMin.Web" />
</sectionGroup>
…
</configSections>
…
<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
<core>
<html removeRedundantAttributes="true"
removeHttpProtocolFromAttributes="true"
removeHttpsProtocolFromAttributes="true" />
<xhtml removeRedundantAttributes="true"
removeHttpProtocolFromAttributes="true"
removeHttpsProtocolFromAttributes="true" />
<xml collapseTagsWithoutContent="true" />
<css defaultMinifier="MsAjaxCssMinifier">
<minifiers>
<add name="NullCssMinifier"
displayName="Null CSS Minifier"
type="WebMarkupMin.Core.Minifiers.NullCssMinifier, WebMarkupMin.Core" />
<add name="KristensenCssMinifier"
displayName="Mads Kristensen's CSS minifier"
type="WebMarkupMin.Core.Minifiers.KristensenCssMinifier, WebMarkupMin.Core" />
<add name="MsAjaxCssMinifier"
displayName="Microsoft Ajax, CSS Minifier"
type="WebMarkupMin.MsAjax.Minifiers.MsAjaxCssMinifier, WebMarkupMin.MsAjax" />
</minifiers>
</css>
<js defaultMinifier="MsAjaxJsMinifier">
<minifiers>
<add name="NullJsMinifier"
displayName="Null JS Minifier"
type="WebMarkupMin.Core.Minifiers.NullJsMinifier, WebMarkupMin.Core" />
<add name="CrockfordJsMinifier"
displayName="Douglas Crockford's JS Minifier"
type="WebMarkupMin.Core.Minifiers.CrockfordJsMinifier, WebMarkupMin.Core" />
<add name="MsAjaxJsMinifier"
displayName="Microsoft Ajax JS Minifier"
type="WebMarkupMin.MsAjax.Minifiers.MsAjaxJsMinifier, WebMarkupMin.MsAjax" />
</minifiers>
</js>
<logging defaultLogger="MyLogger">
<loggers>
<add name="NullLogger"
displayName="Null Logger"
type="WebMarkupMin.Core.Loggers.NullLogger, WebMarkupMin.Core" />
<add name="ThrowExceptionLogger"
displayName="Throw exception logger"
type="WebMarkupMin.Core.Loggers.ThrowExceptionLogger, WebMarkupMin.Core" />
<add name="MyLogger"
displayName="My logger"
type="TestAspNetMvc5.MyLogger, TestAspNetMvc5" />
</loggers>
</logging>
</core>
<msAjax>
<css colorNames="Major" />
<js quoteObjectLiteralProperties="true" />
</msAjax>
<webExtensions disableMinificationInDebugMode="false"
disableCompressionInDebugMode="false" />
</webMarkupMin>
…
</configuration>

Далі я воспроизведу ці налаштування засобами нової моделі конфігурації.

Налаштування ASP.NET 4.X-розширень багато в чому нагадує настройку Microsoft ASP.NET Web Optimization Framework.

У веб-застосунках ASP.NET MVC і Web Forms налаштування WebMarkupMin проводиться у файлі
App_Start/WebMarkupMinConfig.cs
:

using System.Collections.Generic;

using WebMarkupMin.AspNet.Common;
using WebMarkupMin.AspNet.Common.UrlMatchers;
using WebMarkupMin.AspNet4.Common;
using WebMarkupMin.Core;
using WebMarkupMin.MsAjax;

namespace TestAspNetMvc5
{
public class WebMarkupMinConfig
{
public static void Configure(WebMarkupMinConfiguration configuration)
{
configuration.AllowMinificationInDebugMode = true;
configuration.AllowCompressionInDebugMode = true;

IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
htmlMinificationManager.ExcludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
htmlMinificationManager.MinificationSettings = new HtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};

IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
xhtmlMinificationManager.IncludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
xhtmlMinificationManager.MinificationSettings = new XhtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};

IXmlMinificationManager xmlMinificationManager = XmlMinificationManager.Current;
xmlMinificationManager.MinificationSettings = new XmlMinificationSettings
{
CollapseTagsWithoutContent = true
};

DefaultCssMinifierFactory.Current = new MsAjaxCssMinifierFactory(
new MsAjaxCssMinificationSettings { ColorNames = CssColor.Major }
);
DefaultJsMinifierFactory.Current = new MsAjaxJsMinifierFactory(
new MsAjaxJsMinificationSettings { QuoteObjectLiteralProperties = true }
);
DefaultLogger.Current = new MyLogger();
}
}
}

Ці налаштування практично ідентичні налаштувань з файлу
Веб.config
, за винятком однієї маленької деталі – тут показаний приклад використання властивостей
IncludedPages
та
ExcludedPages
(у попередній версії не було такого функціоналу). В даному прикладі, з допомогою цих властивостей ми ділимо всі сторінки сайту з типом вмісту
text/html
на 2 групи: одні обробляються HTML-минификатором, а інші XHTML-минификатором. Такий поділ навряд чи стане в нагоді в реальному житті, але зате досить наочно показує, як користуватися цими конфігураційними властивостями.

Інший момент, на якому я хотів би зупинитися, – це використання фабрик CSS і JS-минификаторов. Раніше при налаштуванні ASP.NET-розширень ми вказували імена CSS і JS-минификаторов, а зараз замість них ми використовуємо примірники фабрик.

У версії 1.X при створенні примірників таких минификаторов виконувалися 3 дії:

  1. Пошук в конфігураційному файлі імені минификатора інформації про відповідний .NET-тип.
  2. Створення екземпляра .NET-типу.
  3. Завантаження налаштувань минификатора з конфігураційного файлу.
У версії 2.X ми одразу маємо примірник відповідної фабрики, яка створює примірники минификаторов з потрібними нам налаштуваннями. Відповідно є 2 інтерфейсу для таких фабрик:
ICssMinifierFactory
та
IJsMinifierFactory
. Фабрики завжди йдуть в комплекті з минификаторами, т.тобто для кожного CSS — або JS-минификатора є своя фабрика.

В даному прикладі за допомогою класів
DefaultCssMinifierFactory
та
DefaultJsMinifierFactory
, ми визначаємо фабрики за замовчуванням. Ці фабрики будуть використовуватися менеджерами минификации, тільки в разі, якщо ми не задали фабрики явно. Для явного присвоєння примірників фабрик менеджерам HTML і XHTML-минификации використовуються властивості
CssMinifierFactory
та
JsMinifierFactory
:

…
using WebMarkupMin.MsAjax;
using WebMarkupMin.Yui;

namespace TestAspNetMvc5
{
public class WebMarkupMinConfig
{
public static void Configure(WebMarkupMinConfiguration configuration)
{
…
IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
…
htmlMinificationManager.CssMinifierFactory = new MsAjaxCssMinifierFactory();
htmlMinificationManager.JsMinifierFactory = new MsAjaxJsMinifierFactory();

IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
…
xhtmlMinificationManager.CssMinifierFactory = new YuiCssMinifierFactory();
xhtmlMinificationManager.JsMinifierFactory = new YuiJsMinifierFactory();
…
}
}
}

Для того, щоб налаштування з файлу
App_Start/WebMarkupMinConfig.cs
вступили в силу, потрібно додати виклик методу
WebMarkupMinConfig.Configure
файл
Global.asax
:

…
using System.Web.Routing;

using WebMarkupMin.AspNet4.Common;

namespace TestAspNetMvc5
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
…
RouteConfig.RegisterRoutes(RouteTable.Routes);
WebMarkupMinConfig.Configure(WebMarkupMinConfiguration.Instance);
}
}
}

На сайтах ASP.NET Web Pages замість файлів
App_Start/WebMarkupMinConfig.cs
та
Global.asax
для налаштування використовується тільки один файл —
_AppStart.cshtml
:

@using WebMarkupMin.AspNet.Common
@using WebMarkupMin.AspNet.Common.UrlMatchers
@using WebMarkupMin.AspNet4.Common
@using WebMarkupMin.Core
@using WebMarkupMin.MsAjax

@using TestAspNetWebPages3

@{
…
#region WebMarkupMin configuration

WebMarkupMinConfiguration configuration = WebMarkupMinConfiguration.Instance;
configuration.AllowMinificationInDebugMode = true;
configuration.AllowCompressionInDebugMode = true;

IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
htmlMinificationManager.ExcludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
htmlMinificationManager.MinificationSettings = new HtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};

IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
xhtmlMinificationManager.IncludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
xhtmlMinificationManager.MinificationSettings = new XhtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};

IXmlMinificationManager xmlMinificationManager = XmlMinificationManager.Current;
xmlMinificationManager.MinificationSettings = new XmlMinificationSettings
{
CollapseTagsWithoutContent = true
};

DefaultCssMinifierFactory.Current = new MsAjaxCssMinifierFactory(
new MsAjaxCssMinificationSettings { ColorNames = CssColor.Major }
);
DefaultJsMinifierFactory.Current = new MsAjaxJsMinifierFactory(
new MsAjaxJsMinificationSettings { QuoteObjectLiteralProperties = true }
);
DefaultLogger.Current = new MyLogger();

#endregion
}

Даний приклад не потребує коментарів, оскільки абсолютно ідентичний попередньому.

Модель конфігурації ASP.NET Core-розширення
Опції ASP.NET-розширення
Клас
WebMarkupMinOptions
на додаток до властивостей, наслідуваних від класу
WebMarkupMinConfigurationBase
, також має свої власні властивості:





Властивість Тип даних Значення за замовчуванням Опис
AllowMinificationInDevelopmentEnvironment
Булевский
false
Дозволяє минификацию розмітки development-середовищі.
AllowCompressionInDevelopmentEnvironment
Булевский
false
Дозволяє HTTP-стиснення текстового вмісту в development-середовищі.
У новій версії ASP.NET відсутнє таке поняття як режим відладки, замість цього використовується поняття поточна середовище. Ім'я поточної середовища визначається значенням змінної оточення
ASPNETCORE_ENVIRONMENT
. Цій змінній можна присвоїти будь-яке значення, але є 3 значення, які були визначені розробниками фреймворку:
Development
,
Staging
та
Production
.

За замовчуванням development-середовищі відключена минификация і HTTP-стиснення. Щоб включити їх потрібно присвоїти перерахованим вище конфігураційним властивостям значення рівне
true
або змінити ім'я поточної середовища на відмінну від
Development
.

Особливості налаштування
На початку статті було показано, як підключити модулі (можливості) з пакету WebMarkupMin.AspNetCore1. У цьому розділі ми розглянемо, яким чином можна їх налаштувати. Для налаштування ми будемо використовувати 2 можливості нового ASP.NET: фреймворк Microsoft.Extensions.Options і вбудований механізм впровадження залежностей. В якості прикладу знову відтворимо налаштування з розділу «Модель конфігурації ASP.NET 4.X-розширень»:

using System.Collections.Generic;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using WebMarkupMin.AspNet.Common.UrlMatchers;
using WebMarkupMin.AspNetCore1;
using WebMarkupMin.Core;
using WebMarkupMin.NUglify;

namespace TestAspNetCore1
{
public class Startup
{
…
// This method gets called by the runtime.
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
…
// Add WebMarkupMin services.
services.AddWebMarkupMin(options =>
{
options.AllowMinificationInDevelopmentEnvironment = true;
options.AllowCompressionInDevelopmentEnvironment = true;
})
.AddHtmlMinification(options =>
{
options.ExcludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
options.MinificationSettings = new HtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};
})
.AddXhtmlMinification(options =>
{
options.IncludedPages = new List<IUrlMatcher>
{
new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
new ExactUrlMatcher("/contact")
};
options.MinificationSettings = new XhtmlMinificationSettings
{
RemoveRedundantAttributes = true,
RemoveHttpProtocolFromAttributes = true,
RemoveHttpsProtocolFromAttributes = true
};
})
.AddXmlMinification(options =>
{
options.MinificationSettings = new XmlMinificationSettings
{
CollapseTagsWithoutContent = true
};
})
.AddHttpCompression()
;

services.AddSingleton<ICssMinifierFactory>(new NUglifyCssMinifierFactory(
new NUglifyCssMinificationSettings { ColorNames = CssColor.Major }
));
services.AddSingleton<IJsMinifierFactory>(new NUglifyJsMinifierFactory(
new NUglifyJsMinificationSettings { QuoteObjectLiteralProperties = true }
));
services.AddSingleton<WebMarkupMin.Core.Loggers.ILogger, MyLogger>();
…
}
…
}
}

З наведеного вище коду видно, що методи, які ми використовували для підключення модулів, тепер беруть у якості параметрів делегати, через які проводиться настройка опцій.

З допомогою впровадження залежностей ми перевизначаємо, використовувані за замовчуванням фабрики минификаторов і логгер. Також з коду видно, що в цьому прикладі ми використовуємо замість пакета WebMarkupMin.MsAjax його аналог — WebMarkupMin.NUglify, який сумісний з .NET Core.

Посилання
  1. Сторінка проекту WebMarkupMin на GitHub
  2. Документація WebMarkupMin версії 2.X
  3. Моя стаття «WebMarkupMin HTML Minifier – сучасний HTML-мінімізатори для платформи .NET»
  4. Сторінка проекту NUglify
  5. Стаття Віктора Коцюбана «Готуємо ASP.NET5, випуск №3 — впровадження залежностей по-новому»
  6. Розділ «Dependency Injection» з документації ASP.NET Core.
  7. Розділ «Working with Multiple Environments» з документації ASP.NET Core.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.