Bundle Transformer: Літні оновлення

Логотип Bundle Transformer на сільськогосподарському полі

Починаючи з вересня минулого року, коли бібліотека MSIE JavaScript Engine for .NET була замінена бібліотекою JavaScript Engine Switcher і був створений модуль BundleTransformer.CleanCss, в Bundle Transformer практично не було якихось революційних змін. Зміни були в основному еволюційними: додавалася підтримка нових версій мінімізаторів та трансляторів (сама рутинна і складна частина роботи над проектом), виправлялися дрібні помилки і йшла робота над збільшенням продуктивності.

Але цього літа все змінилося: з кінця травня по липень від користувачів Bundle Transformer було отримано величезну кількість рекомендацій щодо поліпшення проекту. Велика частина з них була реалізована у версії 1.9.0 і наступних літніх оновленнях. У даній статті ми розглянемо найбільш значущі з них:

Класи StyleTransformer і ScriptTransformer
Спочатку для класів
CssTransformer
та
JsTransformer
були обрані не зовсім вдалі імена, тому що вибір імен проводився за аналогією з класами
CssMinify
та
JsMinify
з System.Web.Optimization. Коли в System.Web.Optimization з'явилися класи
StyleBundle
та
ScriptBundle
, то стало зрозуміло, що ці назви нікуди не годяться.

Я довго відкладав перейменування цих класів на потім, але при роботі над версією 1.9.0 я вирішив їх все-таки перейменувати. Тепер вони називаються
StyleTransformer
та
ScriptTransformer
. Старі класи
CssTransformer
та
JsTransformer
, як і раніше доступні в ядрі (реалізовані як обгортки над новими класами), але вони вважаються застарілими (позначені атрибутом
Obsolete
), і будуть видалені у версії 2.0.0.

Постпроцессоры
В кінці травня мені прийшов pull request «Support for Autoprefixer» від Вегарда Ларсена (співробітника норвезької компанії Digital Creations). При перегляді коду відразу стало зрозуміло, що поточна архітектура Bundle Transformer не підходить для реалізації таких модулів. Вегард реалізував функціонал цього модуля у вигляді транслятора стилів, який повинен був запускатися після всіх інших трансляторів (LESS, Sass тощо). Вся ця реалізація виглядала як хак, тому я прийняв рішення відхилити даний pull request. В результаті Вегард опублікував у NuGet неофіційну версію модуля — BundleTransformer.Autoprefixer.Unofficial, а я почав роботу над новою архітектурою Bundle Transformer.

Потрібен був новий тип модулів, які повинні були запускатися після трансляторів і перед мінімізаторами, причому кількість і порядок виклику таких модулів повинен визначатися розробником. В якості назви для нового типу модулів я вирішив використовувати термін «постпроцессоры», який придумав Андрій Ситник (якщо ви не знаєте, хто такий Андрій Ситник або що таке постпроцессоры, то рекомендую вам прослухати 6-й випуск подкасту Frontflip).

Постпроцессором в Bundle Transformer може бути будь-клас, який реалізує інтерфейс
IPostProcessor
або наступний базовий клас
PostProcessorBase
з простору імен
BundleTransformer.Core.PostProcessors
. Як і інші типи модулів (адаптерів) постпроцессоры повинні бути зареєстровані в файл
Web.config
. Розглянемо процес реєстрації на прикладі CSS-постпроцесорів:

<configuration>
… 
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<core …>
<css defaultPostProcessors="UrlRewritingCssPostProcessor,AutoprefixCssPostProcessor" …>
<postProcessors>
<add name="UrlRewritingCssPostProcessor"
type="BundleTransformer.Core.PostProcessors.urlrewritingcsspostprocessor, BundleTransformer.Core"
useInDebugMode="false" />
<add name="AutoprefixCssPostProcessor"
type="BundleTransformer.Autoprefixer.Postprocessors.autoprefixcsspostprocessor, BundleTransformer.Autoprefixer"
useInDebugMode="true" />
</postProcessors>
</css>
…
</core>
…
</bundleTransformer>
…
</configuration>

У елементі
/configuration/bundleTransformer/core/css/postProcessors
зареєстровані два постпроцесора:
  1. UrlRewritingCssPostProcessor. Виробляє перетворення відносних шляхів в абсолютні (стандартна можливість Bundle Transformer, реалізована у вигляді постпроцесора).
  2. AutoprefixCssPostProcessor. Додає підтримку Autoprefixer'а в Bundle Transformer.
На перший погляд, це дуже схоже на реєстрацію мінімізаторів, але є одна невелика відмінність: якщо в атрибуті
defaultMinifier
елементу
/configuration/bundleTransformer/core/css
ми можемо вказати тільки один мінімізатори, то в атрибуті
defaultPostProcessors
ми можемо задати будь-яку кількість постпроцесорів (навіть нульове). Причому порядок, в якому ми вказуємо імена постпроцесорів у цьому атрибуті, визначає порядок їх виконання. Якщо атрибут відсутній, то як постпроцесора за замовчуванням використовується
UrlRewritingCssPostProcessor
.

З коду також видно, що значення атрибута
useInDebugMode
у постпроцесорів розрізняється: у
UrlRewritingCssPostProcessor
воно дорівнює
false
(перетворення відносних шляхів в абсолютні потрібно тільки в режимі випуску, коли всі файли об'єднуються в один), а у
AutoprefixCssPostProcessor
true
(актуалізація вендорних префіксів потрібна і в режимі налагодження, і в режимі випуску).

Реєстрація JavaScript-постпроцесорів практично нічим не відрізняється від реєстрації CSS-постпроцесорів, за винятком того, що вона повинна вироблятися в конфігураційному елементі
/configuration/bundleTransformer/core/js
.

Вдосконалені налагоджувальні HTTP хендлери
Як правило, більшість користувачів Bundle Transformer налаштовують модулі декларативним способом (через
Web.config
), але в деяких випадках доводиться використовувати імперативний підхід. Наприклад, при роботі з LESS-змінними:

using System.Collections.Generic;
using System.Web.Optimization;

using BundleTransformer.Core.Builders;
using BundleTransformer.Core.Orderers;
using BundleTransformer.Core.Transformers;
using BundleTransformer.Core.Translators;
using BundleTransformer.Less.Translators;

public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var nullBuilder = new NullBuilder();
var nullOrderer = new NullOrderer();

var lessTranslator = new LessTranslator
{
GlobalVariables = "my-variable='Hurrah!'",
ModifyVariables = "font-family-base='Comic Sans MS';body-bg=lime;font-size-h1=50px"
};
var styleTransformer = new StyleTransformer(
new List<ITranslator> { lessTranslator });

var commonStylesBundle = new Bundle("~/Bundles/BootstrapStyles");
commonStylesBundle.Include("~/Content/bootstrap/bootstrap.less");
commonStylesBundle.Builder = nullBuilder;
commonStylesBundle.Transforms.Add(styleTransformer);
commonStylesBundle.Orderer = nullOrderer;
bundles.Add(commonStylesBundle);
}
}

У наведеному вище коді ми створюємо екземпляр класу
LessTranslator
та за допомогою властивостей
GlobalVariables
та
ModifyVariables
виробляємо налаштування LESS-змінних. При такому підході ми можемо передавати виконавцю значення LESS-змінних, отримані з зовнішнього джерела (наприклад, бази даних).

Існує і другий спосіб роботи з LESS-змінними. Спочатку потрібно створити власну трансформацію елемента:

using System.Text;
using System.Web.Optimization;

public sealed class InjectContentItemTransform : IItemTransform
{
private readonly string _beforeContent;
private readonly string _afterContent;

public InjectContentItemTransform(string beforeContent, string afterContent)
{
_beforeContent = beforeContent ?? string.Empty;
_afterContent = afterContent ?? string.Empty;
}

public string Process(string includedVirtualPath, string input)
{
if (_beforeContent.Length == 0 && _afterContent.Length == 0)
{
return input;
}

var contentBuilder = new StringBuilder();
if (_beforeContent.Length > 0)
{
contentBuilder.AppendLine(_beforeContent);
}
contentBuilder.AppendLine(input);
if (_afterContent.Length > 0)
{
contentBuilder.AppendLine(_afterContent);
}

return contentBuilder.ToString();
}
}

А потім зареєструвати її при додаванні файлу в бандл:

using System.Web.Optimization;

using BundleTransformer.Core.Bundles;
using BundleTransformer.Core.Orderers;

public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var nullOrderer = new NullOrderer();

const string beforeLessCodeToInject = @"@my-variable: 'Hurrah!';";
const string afterLessCodeToInject = @"@font-family-base: 'Comic Sans MS';
@body-bg: lime;
@font-size-h1: 50px;";

var commonStylesBundle = new CustomStyleBundle("~/Bundles/BootstrapStyles");
commonStylesBundle.Include(
"~/Content/bootstrap/bootstrap.less",
new InjectContentItemTransform(beforeLessCodeToInject, afterLessCodeToInject));
commonStylesBundle.Orderer = nullOrderer;
bundles.Add(commonStylesBundle);
}
}

На жаль, наведені вище приклади коду раніше працювали тільки в режимі випуску. Це було викликано тим, що налагоджувальні HTTP хендлери нічого «не знали» про налаштування бандлів і просто транслювали код запитуваних файлів.

Щоб вирішити цю проблему потрібно було, в першу чергу, знайти спосіб передати випробувальні HTTP хендлер URL пакету, в який входить запитуваний файл. Після вивчення коду складання
System.Web.Optimization.dll
з допомогою декомпилятора рішення було знайдено: потрібно написати свою власну версію класу
BundleResolver
та зареєструвати його у відповідному класі. Я не буду вдаватися в деталі реалізації, а просто покажу, як використовувати створений клас:

…
using BundleTransformer.Core.Resolvers;

public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
BundleResolver.Current = new CustomBundleResolver();
…
}
}

Після цього в режимі налагодження будуть генеруватися посилання на файли наступного виду:

<link
href="/Content/bootstrap/bootstrap.less?bundleVirtualPath=%7e%2fBundles%2fBootstrapStyles"
rel="stylesheet">

, де параметр рядка запиту
bundleVirtualPath
містить URL бандла.

Таким чином, маючи в розпорядженні URL бандла я додав в базовий налагоджувальний HTTP хендлер можливість застосовувати до запитуваного файлу, прив'язані до нього користувальницькі трансформації елементів та трансформації, задані на рівні бандла (транслятори і постпроцессоры).

Крім того, були створені два додаткових HTTP хендлер:
  1. CssAssetHandler. Для обробки CSS-файлів.
  2. JsAssetHandler. Для обробки JavaScript-файлів.
Вони дозволяють застосовувати до статичних файлів користувальницькі трансформації елементів та постпроцессоры. Якщо запитуваний статичний файл не входить ні в один з бандлів, то ці HTTP хендлери передають запит екземпляру класу
System.Web.StaticFileHandler
. На відміну, від налагоджувальних HTTP хэнлеров, що йдуть в комплекті з трансляторами, дані HTTP хендлери не реєструються у файлі
Web.config
автоматично (під час установки NuGet-пакетів), їх необхідно реєструвати вручну:

<configuration>
…
<system.webServer>
…
<handlers>
…
<add name="CssAssetHandler" path="*.css" verb="GET" 
type="BundleTransformer.Core.HttpHandlers.cssassethandler, BundleTransformer.Core" 
resourceType="File" preCondition="" />
<add name="JsAssetHandler" path="*.js" verb="GET" 
type="BundleTransformer.Core.HttpHandlers.jsassethandler, BundleTransformer.Core" 
resourceType="File" preCondition="" />
…
</handlers>
…
</system.webServer>
…
</configuration>

Зіставлення розширень файлів і типів ресурсів у файлі Web.config
Раніше зіставлення розширень файлів і типів ресурсів було жорстко зашито в коді класу
Asset
. Тепер для цього використовуються конфігураційні елементи
fileExtensions
файл
Web.config
:

<configuration>
…
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<core …>
<css …>
…
<fileExtensions>
<add fileExtension=".css" assetTypeCode="Css" />
<add fileExtension=".less" assetTypeCode="Less" />
<add fileExtension=".sass" assetTypeCode="Sass" />
<add fileExtension=".scss" assetTypeCode="Scss" />
</fileExtensions>
</css>
<js …>
…
<fileExtensions>
<add fileExtension=".js" assetTypeCode="JavaScript" />
<add fileExtension=".coffee" assetTypeCode="CoffeeScript" />
<add fileExtension=".litcoffee" assetTypeCode="LiterateCoffeeScript" />
<add fileExtension=".coffee.md" assetTypeCode="LiterateCoffeeScript" />
<add fileExtension=".ts" assetTypeCode="TypeScript" />
<add fileExtension=".mustache" assetTypeCode="Mustache" />
<add fileExtension=".handlebars" assetTypeCode="Handlebars" />
<add fileExtension=".hbs" assetTypeCode="Handlebars" />
</fileExtensions>
</js>
…
</core>
…
</bundleTransformer>
…
</configuration>

У наведеному вище прикладі показана ситуація, коли встановлені всі офіційні модулі Bundle Transformer (зіставлення для розширень
.css
та
.js
додаються при встановленні ядра, а інші при встановленні відповідних модулів-трансляторів). Така архітектура дає нам наступні переваги:
  1. Не потрібно зберігати невикористовувані зіставлення. Як правило, в реальних проектах не потрібно встановлювати всі види трансляторів (наприклад, одночасне використання LESS і Sass зустрічається дуже рідко), таким чином в проекті буде зберігатися меншу кількість зіставлень.
  2. Можливість створення неофіційних модулів-трансляторів. Оскільки тепер немає залежності від коду ядра, то у користувачів Bundle Transformer з'явилася можливість створювати власні модулі-транслятори. Прикладом такого модуля може служити NuGet-пакет AngularBundle, при установці якого в файл
    Web.config
    додається наступне зіставлення:

    <configuration>
    …
    <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
    <core>
    …
    <js …>
    …
    <fileExtensions>
    …
    <add fileExtension=".html" assetTypeCode="AngularTemplate" />
    …
    </fileExtensions>
    </js>
    …
    </core>
    …
    </bundleTransformer>
    …
    </configuration>

  3. Прив'язка нових розширень файлів до існуючих модулів-трансляторам. Наприклад, якщо ми хочемо, щоб модуль BundleTransformer.Hogan почав обробляти файли з розширенням
    .html
    , нам потрібно просто додати наступний код у файл
    Веб.config
    :

    <configuration>
    …
    <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
    <core …>
    …
    <js …>
    …
    <fileExtensions>
    …
    <add fileExtension=".html" assetTypeCode="Mustache" />
    …
    </fileExtensions>
    </js>
    …
    </core>
    …
    </bundleTransformer>
    …
    <system.webServer>
    …
    <handlers>
    …
    <add name="HtmlAssetHandler" path="*.html" verb="GET"
    type="BundleTransformer.Hogan.HttpHandlers.hoganassethandler, BundleTransformer.Hogan"
    resourceType="File" preCondition="" />
    …
    </handlers>
    …
    </system.webServer>
    …
    </configuration>
Об'єднання коду файлів перед мінімізацією
Bundle Transformer, на відміну від System.Web.Optimization, обробляє кожен файл окремо і такий підхід дає ряд переваг:
  1. З'являється можливість об'єднувати в один пакет різні типи ресурсів (наприклад, CSS, LESS — і Sass-файли).
  2. Не проводиться повторна мінімізація попередньо минимизированных файлів (файли з розширеннями
    .min.css
    та
    .min.js
    ), що в більшості випадків збільшує швидкість мінімізації при первинному зверненні до бандлу.
Але деяким користувачам Bundle Transformer не подобався даний підхід, тому що вони хотіли повною мірою використовувати можливості структурної мінімізації, які надають сучасні мінімізатори (наприклад, CSSO від компанії Яндекс).

Тому в новій версії у конфігураційних елементів
css
та
js
з'явився атрибут
combineFilesBeforeMinification
(значення за замовчуванням —
false
), який дозволяє включити об'єднання коду файлів перед мінімізацією:

<configuration>
…
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<core 
<css … combineFilesBeforeMinification="true">
…
</css>
<js … combineFilesBeforeMinification="true">
…
</js>
…
</core>
…
</bundleTransformer>
…
</configuration>

Нові модулі
За цей час для Bundle Transformer було створено відразу три офіційних модуля:
  1. Постпроцесор BundleTransformer.Autoprefixer
  2. Транслятор BundleTransformer.Handlebars
  3. Транслятор BundleTransformer.Hogan
Оскільки всі три модулі засновані на коді JavaScript-бібліотек, то відразу після установки вам потрібно для кожного з них вибрати свій JavaScript-движок (більш детальну інформацію дивіться у файлі
readme.txt
відповідних NuGet-пакетів).

Розглянемо кожен з них окремо:

Bundle Transformer: Autoprefixer
Модуль BundleTransformer.Autoprefixer містить адаптер-постпроцесор
AutoprefixCssPostProcessor
, що виробляє актуалізацію вендорних префіксів в CSS-коді.
AutoprefixCssPostProcessor
створений на основі популярного CSS-постпроцесора — Autoprefixer (на даний момент підтримується версія 3.1). Я не буду пояснювати для чого потрібен Autoprefixer, тому що всю основну інформацію про даному продукті ви можете підкреслити зі статті Андрія Ситника «Автопрефиксер — остаточне рішення проблеми префіксів в CSS».

У цьому розділі я розповім про те, як правильно налаштувати BundleTransformer.Autoprefixer. Якщо ви не читали розділи «Постпроцессоры» і «Вдосконалені налагоджувальні HTTP хендлер» даної статті, то обов'язково прочитайте їх, тому що в них зачіпаються багато важливих моменти, пов'язані з роботою BundleTransformer.Autoprefixer.

Після установки BundleTransformer.Autoprefixer і вибору JavaScript-движка вам потрібно виконати наступні дії:
  1. Додати постпроцесор
    AutoprefixCssPostProcessor
    в кінець списку активних CSS-постпроцесорів, який задається в атрибуті
    defaultPostProcessors
    конфігураційного елемента
    /configuration/bundleTransformer/core/css
    .
  2. Зареєструвати налагоджувальний HTTP хендлер
    CssAssetHandler
    файл
    Web.config
    (потрібно для режиму налагодження).
  3. Зареєструвати екземпляр класу
    CustomBundleResolver
    в якості поточного
    BundleResolver
    `а (потрібно для режиму налагодження).
Потім в конфігураційної секції
/configuration/bundleTransformer/autoprefixer
файл
Web.config
можна зробити необов'язкові параметри алгоритму Autoprefixer'а:

<configuration>
…
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
…
<autoprefixer cascade="true" safe="false">
<browsers>
<add conditionalExpression="> 1%" />
<add conditionalExpression="last 2 versions" />
<add conditionalExpression="Firefox ESR" />
<add conditionalExpression="Opera 12.1" />
</browsers>
…
</autoprefixer>
…
</bundleTransformer>
…
</configuration>

Докладно розглянемо всі властивості конфігураційної секції
autoprefixer
:
Властивість Тип даних Значення за замовчуванням Опис
browsers
Список умовних виразів
1%
,
last 2 versions
,
Firefox ESR
,
Opera 12.1
Містить список умовних виразів для визначення підмножини підтримуваних браузерів. Синтаксис умовних виразів докладно описаний в офіційній документації Autoprefixer'а. Якщо елемент
browsers
не зазначено або порожній, то використовується значення за замовчуванням. Щоб повністю відключити додавання вендорних префіксів потрібно залишити в елементі
browsers
всього одне умовне вираз дорівнює
none
.
cascade
Булевский
true
Створює візуальний каскад з префіксів наступного виду:

-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
safe
Булевский
false
Включає спеціальний безпечний режим для парсингу зламаного CSS-коду.
Bundle Transformer: Handlebars
Модуль BundleTransformer.Handlebars містить адаптер-транслятор
HandlebarsTranslator
, що виробляє прекомпиляцию Handlebars-шаблонів в JavaScript.
HandlebarsTranslator
створений на основі популярного шаблонизатора — Handlebars.js (на даний момент підтримується версія 2.0.0). Незважаючи на те, що даний транслятор створений на основі шаблонизатора, він мало чим відрізняється від інших трансляторів, що дають на виході JavaScript-код. Файли з кодом шаблонів (за замовчуванням транслятором обробляються файли з розширеннями
.handlebars
та
.hbs
) потрібно реєструвати в скриптових бандлах:

…
using Core.Bundles;
using Core.Orderers;
…

public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
…
var commonTemplatesBundle = new CustomScriptBundle("~/Bundles/CommonTemplates");
commonTemplatesBundle.Include(
…
"~/Scripts/handlebars/handlebars.runtime.js",
"~/Scripts/handlebars/HandlebarsHelpers.js",
"~/Scripts/handlebars/HandlebarsTranslatorBadge.handlebars",
…);
commonTemplatesBundle.Orderer = nullOrderer;
bundles.Add(commonTemplatesBundle);
… 
}
}

На відміну від CoffeeScript і TypeScript скомпільовані Handlebars-шаблони вимагають наявності файлу
handlebars.runtime.js
(урізана версія бібліотеки
handlebars.js
, з якої виключений код, необхідний для компіляції шаблонів). Цей файл можна розмістити у бандл з спільними бібліотеками або в бандл з Handlebars-шаблонами. Головне, щоб його оголошення йшло перед оголошенням шаблонів.

У конфігураційної секції
/configuration/bundleTransformer/handlebars
файл
Web.config
можна зробити налаштування прекомпиляции шаблонів:

<configuration>
…
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
…
<handlebars namespace="Handlebars.templates" rootPath=""
knownHelpers="link" knownHelpersOnly="true" data="false">
…
</handlebars>
…
</bundleTransformer>
…
</configuration>

Докладно розглянемо всі властивості конфігураційної секції
handlebars
:
Властивість Тип даних Значення за замовчуванням Опис
namespace
Рядок
Handlebars.templates
Задає простір імен шаблонів.
rootPath
Рядок Порожній рядок Задає шлях до кореневої директорії шаблонів. Припустимо, що у нас є наступний URL шаблон —
/Scripts/handlebars/discussions/index.hbs
. За замовчуванням ім'я такого шаблону витягується з імені файлу —
index
, але якщо ми присвоїмо цій властивості значення рівне
/Scripts/handlebars/
, то отримаємо наступне ім'я шаблону —
discussions/index
.
knownHelpers
Рядок Порожній рядок Містить розділений комами список відомих хелперів. Додавання імен хелперів в цей список дозволяє оптимізувати звернення до них, що призводить до зменшення розміру скомпільованого шаблону.
knownHelpersOnly
Булевский
false
Дозволяє використовувати тільки відомі хелпери. Якщо значення дорівнює
true
та код шаблону містить виклики хелперів, які не є вбудованими або не оголошені властивості
knownHelpers
, то буде видано виняток.
data
Булевский
true
Дозволяє при компіляції включати в шаблони дані для @data-змінних (наприклад,
@index
). Якщо у ваших шаблонах є ітераційне блоки, але не використовуються @data-змінні, то краще дайте цій властивості значення рівне
false
— це збільшить продуктивність.
Також варто відзначити, що якщо ім'я файлу, що містить код шаблону, починається з підкреслення, то шаблон буде складати як глобальне часткове уявлення (початкова підкреслення буде видалено імені шаблону).

Bundle Transformer: Hogan
Модуль BundleTransformer.Hogan містить адаптер-транслятор
HoganTranslator
, що виробляє прекомпиляцию Mustache-шаблонів в JavaScript.
HoganTranslator
створений на основі популярного компілятора Mustache-шаблонів — Hogan.js (на даний момент підтримується версія 3.0.2). Принципи роботи BundleTransformer.Hogan багато в чому схожі з принципами роботами BundleTransformer.Handlebars, тому ми розглянемо лише ключові відмінності. Файли з кодом шаблонів (за замовчуванням транслятором обробляються файли з розширенням
.mustache
) потрібно реєструвати в скриптових бандлах:

…
using Core.Bundles;
using Core.Orderers;
…

public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
…
var commonTemplatesBundle = new CustomScriptBundle("~/Bundles/CommonTemplates");
commonTemplatesBundle.Include(
"~/Scripts/hogan/template-{version}.js",
"~/Scripts/hogan/HoganTranslatorBadge.mustache",
…);
commonTemplatesBundle.Orderer = nullOrderer;
bundles.Add(commonTemplatesBundle);
…
}
}

Також як і в Handlebars скомпільовані шаблони вимагають наявності спеціальної JavaScript-бібліотеки —
template-3.0.2.js
(в майбутніх релізах номер версії, швидше за все, зміниться).

У конфігураційної секції
/configuration/bundleTransformer/hogan
файл
Web.config
можна зробити налаштування прекомпиляции шаблонів:

<configuration>
…
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
…
<hogan useNativeMinification="false"
variable="templates" namespace="" delimiters="">
<sectionTags>
<add sectionName="newWindow" openingTagName="_newWindow" closingTagName="newWindow" />
</sectionTags>
…
</hogan>
…
</bundleTransformer>
…
</configuration>

Докладно розглянемо всі властивості конфігураційної секції
hogan
:
Властивість Тип даних Значення за замовчуванням Опис
useNativeMinification
Булевский
false
Якщо значення дорівнює
true
, то мінімізація скомпільованого коду шаблону, буде проводитися засобами транслятора.
variable
Рядок
templates
Задає ім'я JavaScript-змінної, в якій будуть зберігатися шаблони.
namespace
Рядок Порожній рядок Задає простір імен, що додається як префікс до імені шаблону.
sectionTags
Список користувацьких тегів Порожній список Містить список користувацьких тегів, які будуть оброблятися як секції. Наприклад, якщо ми додамо власну секцію з ім'ям отрывающегося тега
_newWindow
та ім'ям закривається тега
newWindow
, то код
{{_newWindow}} target="_blank"{{/newWindow}}
обробляється компілятором без помилок.
delimiters
Рядок Порожній рядок Задає рядок, яка замінює стандартні роздільники. Наприклад, якщо ми захочемо замінити стандартні роздільники у вигляді подвійних фігурних дужок на роздільники в стилі ASP, то даній властивості потрібно буде призначено наступне значення —
<% %>
(при додаванні в файл
Web.config
потрібно екранувати спеціальні символи
&lt;% %&gt;
).


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

0 коментарів

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