Open shkarupa-alex opened 8 years ago
@shkarupa-alex Не совсем понял ваш пример. Можете написать что должно в итоге получиться в html?
@shkarupa-alex я могу рассказать, как плюс-минус такое получить, но меня не покидает уверенность, что на самом деле вы этого не хотите.
Предлагаю сначала описать задачу максимально верхнеуровнево, а я попробую посоветовать реализацию, которая доставит минимальное количество боли.
Входные данные (специфика 1С-Битрикс):
В итоге получается что CSS/JS шаблона сайта кешируются и для каждой страницы не скачиваются. А скачивается только то, что на данном типе страниц (список товаров/детальная товара/главная) действительно нужно.
Чтобы из БЭМ-верстки можно было быстро делать шаблоны компонентов, для каждого произвольного DOM-поддерева из сгенерированного сборщиком HTML должно быть максимально очевидно от каких CSS/JS это DOM-поддерево зависит. Наиболее простое решение - в HTML (PHP) комментарии перечислить эти самые CSS/JS. Создавая шаблон компонента из некоторого кусочка HTML программист будет видеть какие CSS/JS ему нужно подключить. Именно это решение я показал в примере https://www.evernote.com/l/AS-PO0Ns7OtKI7oZ-ivE9gzfAjwZHVI5sBc
Таким образом когда производится доработка верстки и генерируются новые HTML становится легко понять что и где нужно изменить (через WinMerge например).
Использовать merged-bundles не хочется по одной причине: в 1С-Битрикс по факту отсутствует понятие "тип страницы". Любая страница может состоять из множества компонентов и добавление/удаление любого из них не должно ломать сайт. Ну и конечно же не все верстальщики настолько продвинуты чтобы быстро и правильно делать конфиги для сборки merged-бандлов.
Более-менее понятно, но есть еще ряд вопросов:
1) Если ли причина не генерировать сразу конкретный код подключения стилей и скриптов вместо комментариев, по которым придется подключать вручную?
2) Что считать сущностью, требующей списка зависимостей? Приведу пример, чтобы было понятно о чем вопрос.
{
block: 'nav',
content: [
{
elem: 'item',
content: {
block: 'link',
url: '#url',
content: {
block: 'icon',
mods: { type: 'info' }
}
}
}
]
}
Это все один блок nav
или 3 разных блока, элемент и модификатор, каждый со своими отдельными зависимостями?
3) После того, как код попал к программисту и он подключил все необходимые зависимости, как дальше развивается проект, если нужно, скажем, добавить модификатор в один из блоков, а у модификатора есть свои собственные зависимости или, наоборот удалить какой-нибудь элемент (и в этот момент определить, нужно ли удалять зависимости элемента или они нужны блоку-родителю)?
Нужно только определить схему, по которой такие файлы должны создаваться
Эту схему я понимаю. Затруднение вызывает вопросы: а) Какую технологию можно для этой задачи взять за основу (есть предположение что нужно изменить поведение bh.apply, переопределив технологию bemjson-to-html) б) Каким образом для конкретного блока/элемента/модификатора bemjson (в рамках bh.apply) получить список всех его зависимостей на CSS/JS (включая зависимости через deps.js)
Будут исключены дублированные зависимости. Битрикс это умеет?
Да, умеет. Даже если 1 и тот же CSS/JS подключен несколько раз, в результирующей странице он появится только однажды. Причем в зависимости от места где он был подключен статический файл он попадет либо в объединенную сборку CSS/JS шаблона, либо в сборку страницы.
Как дальше эти отдельные шаблоны превращаются в страницу?
Страница == PHP (в том числе вызов компонентов) +HTML. Вызов компонента и рендеринг его шаблона происходит на каждый хит. Это если не вдаваться в механизмы кеширования (в т.ч. кеширования отрендеринных шаблонов).
Каждый вызванный компонент рендерит свой шаблон и подставляет результирующий HTML в место вызова. Все необходимые CSS/JS которые затребовали компоненты вставляются в head/body уже после рендеринга всей страницы.
Если генерировать готовые файлы для Битрикса, то bemjson-to-html
вряд ли имеет смысл использовать.
Я бы предложил следующую схему.
У каждого БЭМ-блока есть своя папка. Его непосредственные зависимости описаны в его deps.js
-файле. Поэтому для получения полного списка зависимостей не хватает лишь BEMJSON данного блока.
Самый простой способ хранить такой BEMJSON — это создать каждому блоку маркдаун-файл с документацией, которая в минимальном случае будет состоять из того самого BEMJSON: { block: 'my-block' }
.
Тогда можно будет автоматически собрать CSS и JS для каждого блока автоматически.
Такой вариант подходит?
Хотелось бы более продвинутую технику, которая учитывала: а) Наличие/отсутствие CSS/JS реализаций блока/элемента/модификатора (не генерировала ничего если они отсутствуют) б) Уровни переопределения в) Не требовала верстальщика делать чего-то дополнительного сверх описанного в документации по БЭМ
Я создал в project-stub
ветку forum-630, в которой положил скрипт get-blocks.js.
Принцип такой:
node get-blocks.js desktop.bundles/index/index.bemjson.js
.index.examples/*
.enb.make()
.Сейчас сборка будет собирать CSS и JS полностью, так что для решения исходной задачи потребуется создать технологии для ENB
, которые бы генерировали файлы в нужном для Битрикса формате. Если с этим потребуется помощь — пиши.
Ну и если решение по какой-то причине не подойдет, то можно обсуждать альтернативы.
@tadatuta :fire:
@tadatuta, спасибо за попытку, но не то что нужно.
Пока идея следующая: сделать технологию, которая будет проходить по всем блокам и для каждого блока/элемента/модификатора генерировать json-файл с перечислением зависимостей (как списка CSS/JS, в том числе из других блоков). Для каждого deps.js - делать то же самое (рекурсивно). А уже на этапе рендеринга HTML проверять наличие этого сгенерированного файла и в случае его наличия - вкраплять в HTML нужный код.
Вопрос встал вот за чем: как внутри технологии (а точнее внутри метода builder) правильно интерпретировать deps.js (учитывая что он имеет необязательные части и может отменять зависимости). Наверняка есть какой-то уже готовый метод. Если подскажете его или место где можно посмотреть решение аналогичной задачи - мне будет намного проще реализовать эту больную фантазию.
- В получившихся микросборках если у блока есть зависимость, то результирующий CSS/JS будут склеены (например jQuery будет приклеен в каждый блок который от него зависит)
Это происходит потому что я не менял конфиг сборки для сгенерированных бандлов, они собираются по той же схеме, что и страницы. В данном случае, как я и писал выше, необходимо заменить технологии для сборки CSS и JS на такие, которые бы вместо инлайнинга генерировали необходимый Битриксу формат подключения зависимостей (я с ним не знаком, поэтому сам реализовать не берусь).
- Хочется обойтись без каскадного запуска enb-make
Если внести необходимые изменения по п. 1, то enb make
будет всего лишь рекурсивно собирать зависимости по уровням переопределения и генерировать списки депендов. Т.е. никакой причины пытаться заменить его на что-то самописное нет.
как внутри технологии (а точнее внутри метода builder) правильно интерпретировать deps.js
Вот технология, которая собирает deps: https://github.com/enb-bem/enb-bem-techs/blob/master/techs/deps.js
Хочется сделать такой шаблон BEM-сборки, который бы легко интегрировался в код сайта (с точки зрения программиста) и был оптимизирован в плане подключенных CSS/JS файлов. Речь про CMS 1С-Битрикс у которой своя система сборки/объединения статики. Вариант с merged-бандлами не рассматриваем. Для сборки используем enb + bh.
По факту нужно следующее: а) для каждой БЭМ-сущности понять перечень необходимых для ее работы статических ресурсов (включая зависимости) б) этот самый перечень включить в виде HTML-комментария в результирующей HTML непосредственно перед БЭМ-сущностью (чтобы программист знал какие файлы нужно подключить для каждого кусочка HTML)
Пример для bemjson:
получить html:
Какой вариант вижу я сам: вклиниться в генерацию HTML (BH.apply), вычислять для каждого блока (с учетом миксов), генерировать комментарий и добавлять его в HTML.
Вопросы которые хочу задать: