Open dima117 opened 8 years ago
Спасибо!
Спасибо за пост!
Появился вопрос: планируется ли поддержка ASP.NET Core MVC?
Да, планируется.
Сейчас библиотека EDGE.js, с помощью которой запускается шаблонизатор bem-xjst внутри .NET приложения, поддерживает только .NET 4.5 под Windows. Как только там появится возможность запускать js под .NET Core (или если найдем другой способ) - выпустим новую версию с поддержкой .NET Core.
Если вдруг вы еще не видели, вот продолжение темы и доклад на Я.Субботнике.
До Яндекса я 9 лет работал веб-разработчиком на C#. Мне всегда очень нравилась идея БЭМ и я очень огорчался, что не могу использовать БЭМ-инструменты в проектах на .NET.
Пару раз я пытался подружить .NET и БЭМ, но этому мешало отсутствие инфраструктуры для интеграции JS-инструментов с .NET бэкендом, а создать свою инфраструктуру мешало отсутствие основательных знаний, как это всё должно работать. Сейчас некоторые из этих знаний уже появились в моей голове и текст ниже - описание еще одно попытки создать БЭМ инфраструктуру для .NET.
Итак...
Задача
По сути, задача состоит из двух относительно независимых частей:
Сборка
Простой вариант: запускаем enb.
В мире .NET есть такой сборщик - MsBuild. Именно с помощью него собирается проект, когда вы нажимаете Ctrl + F5 в Visual Studio. По сути, файлы
.sln
и.csproj
, с которыми работает Visual Studio - это конфиги MsBuild. Среди прочего, MsBuild может запускать консольные приложения. Таким образом, мы можем добавить руками в файл проекта вызовenb make
и он будет запускаться при сборке. Достоинства: это просто сделать + сборка на enb хорошо работает. Недостатки: нет интеграции с UI => неудобно настраивать и использовать.Продвинутый вариант: сборка на gulp.
На последнем хакатоне по БЭМ (2-3 апреля 2016) уже был более-менее рабочий пример сборки БЭМ проектов на gulp, а в Visual Studio как раз есть интеграция с gulp с помощью плагина Task Runner Explorer (в последних двух версиях VS этот плагин устанавливается по умолчанию). Достоинства: интеграция с UI + gulp настраивается гибче и удобнее, чем enb + идея с потоками значительно меньше взрывает мозг, чем идея декларативного описания сборки. Ну и gulp намного более распространен. Недостатки: плагины для БЭМ-сборки на gulp еще довольно сырые (об этом ниже).
Что получилось
Файловая структура проекта:
Сборка шаблонов
Вся магия в
bundle.src
- это какgulp.src
, только возвращает файлы из всех уровней переопределения в правильном порядке.Обнаруженные особенности:
bundle.src
падает c неинформативной ошибкой;Спасибо @tadatuta и @zxqfox за помощь и ответы на глупые вопросы.
Сборка js и стилей - аналогично. Весь код можно посмотреть здесь.
Таким образом, получился проект ASP.NET MVC, с которым мы работаем через Visual Studio. В проекте есть папка с БЭМ блоками и при сборке проекта через VS вместе с компиляцией кода на C# происходит сборка БЭМ-бандлов: серверные шаблоны, клиентский js и стили.
Серверная шаблонизация
Чего хотелось иметь в проекте на .NET:
Хочется иметь библиотеку, которую можно подключить к проекту из NuGet и чтобы внутри у нее был полноценный шаблонизатор BEMHTML.
Решено было попробовать запустить bemhtml внутри .NET приложения с помощью какой-нибудь .NET обертки над node. Выбрал EDGE.js. Он умеет запускать ноду внутри .NET процесса (на текущий момент, только на .NET 4.5 под Windows, но написано, что будет и поддержка .NET Core). Созданный экземпляр можно кэшировать, чтобы не создавать несколько раз контекст v8.
Сначала провел небольшой эксперимент - отрендерил простой шаблон в консольном приложении.
Основа всего - вот такой класс:
Ему в конструктор нужно передать текст bemhtml-бандла, сгенерированного с помощью
bemhtml.generate(...)
(это ровно то, что мы делали во время сборки шаблонов). Содержимое бандла примерно такое:Далее мы доклеиваем к этому коду возврат функции, которая будет выполняться при вызове шаблонизации из .NET. Она получает данные и callback, шаблонизирует данные и результат передает входным параметром в callback:
Сгенерированный код мы передаем в
Edge.Func("сгенерированный код")
и получаем экземпляр .NET функцииFunc<object, Task<object>>
, которую можно использовать из программы на C#. Функция - асинхронная (она возвращаетTask<object>
) и мы вызываем ее черезawait
, либо используем примерно таким образом:После того, как в консольном приложении шаблонизация отработала успешно, я написал небольшую библиотеку для использования в веб-приложениях ASP.NET MVC. Там есть:
Что получилось
Сейчас есть небольшое ASP.NET MVC приложение, которое состоит из одной странички, отрендеренной с помощью BEMHTML. В приложение подключены bem-core и bem-components. Страничка открывается и, кажется, всё работает.
Посмотреть код можно здесь, а потыкать мышкой (и посмотреть в инспекторе) можно здесь.
Дальнейшие планы
Также в планах - адаптировать этот текст для людей, ничего не знающих про БЭМ и запостить на хабр.
Спасибо за внимание!