Обязанности bem-deps
- инкрементальное накопление зависимостей в объектной модели
- приём зависимостей в унифицированном формате
- сериализация и десериализация накопленных зависимостей в унифицированный формат и из него (сохранение и чтение)
- манипуляции с множествами зависимостей
- объединение
- пересечение
- вычитание
- вычисление упорядоченного множества БЭМ-сущностей из объектной модели дерева зависимостей по заданным критериям
- инструменты для парсинга зависимостей из исходников
Архитектура
bem-deps
Класс
DepsContainer
Контейнер для инкрементального накопления зависимостей.
Методы инстанса:
add(deps)
— добавляет информацию о зависимостях в контейнер;deps
— чанк, описывающий зависимости в унифицированном форматеserialize()
— сериализует информацию в унифицированный форматforEach()
— хелпер, позволяющий получить необходимое подмножество из объектной модели зависимостей
Статические методы:
deserialize()
— фабрика, создаёт инстансDepsContainer
из сериализованного форматаФормат для хранения зависимостей
TBD
Формат для накопления зависимостей
{
deps: [
{
block: 'block-name', // имя блока
elem: 'elem-name', // имя элемента
mod: 'val' || true // имя и значение модификатора, `true` в качестве значения для булева модификатора
priority: true // флаг приоритета зависимости
}
],
priority: [] // массив для указания приоритета зависимостей без их включения
}
Хелперы для парсинга зависимостей из исходников
Базовый класс DepsParser()
Абстрактный класс, задаёт интерфейс для парсеров зависимостей.
Класс DepsJsParser()
Парсер исходных файлов deps.js
.
Класс DepsYmlParser()
Парсер исходных файлов deps.yaml
.
Класс YmParser()
Парсер исходных js
файлов, использующих модульную систему ym
. Полезен при условии, что имена модулей однозначно соответствуют описываемых в них БЭМ-сущностям.
Утилиты
Утилиты возвращают новый инстанс DepsContainer
с вычисленными зависимостями:
subtract(source, subtraction...)
merge(source...)
intersect(source...)
Раз уж речь о депсах, я бы предложил разделить необходимость подключения зависимости и порядок включения. Как уже замечали,
should
,must
иinclude: false
- непонятная и нелогичная штука. Например:Вместо
forEach
, я бы предложил методquery
с DSL для запросов:deps.query({block: 'a'})
- получить все непосредственные зависимости блокаa
.deps.query({block: 'b', tech: 'js']})
- получить все непосредственные зависимости блокаb
для его технологииjs
.deps.query({block: 'с', tech: 'js', full: true})
- получить полный граф зависимостей для блокаc
(включая зависимости его зависимостей и т.д.). TODO: придумать лучшее название параметруfull
.Можно посмотреть на TaffyDB, можно придумать более специфичную для нас структуру хранения данных.
@SevInf Про
query()
интересно, нужно больше подробностей и примеров использования.Типовые задачи:
js
(или любой другой технологии)bemhtml
зависимостей для сборкиjs
(собирать для клиента только нужные шаблоны)css
(к обычным прямым зависимостям добавляются зависимости других технологий отcss
)Был недавно ещё топик про то, что при сборке бандла
css
нужно собирать для всех блоков, а при сборкеie.css
нужно некоторые зависимости отменять. Надо подумать, можно ли это выразить..query({tech: 'js'});
.query({tech: {'js': 'bemhtml'}})
.query({tech: 'css', full: true})
, если я правильно тебя понял.Тут пока затрудняюсь хорошо ответить. Возможно, какой-то параметр вроде
skip
поможет:Не смог осмыслить почему так.
Посмотрел на deps-resolver из
enb
. Тестов на него нет, jsdoc минимальный, и комментариев по коду нет совсем.Понять, как оно используется можно из кода технологии deps.js.
Особенности реализации:
levels
, в котором в особом формате содержится информация обо всех файлах на всех уровня переопределения, участвующих в сборкеdeps.js
иdeps.yaml
файлы (if
в коде в нескольких местах)tech
ровно одинif
)addDecl()
Есть ещё набор хелперов для работы с зависимостями в модуле lib/deps/deps.js.
Зависимости по технологиям реализованы в отдельной технологии bemdecl-from-deps-by-tech.
Идея там в том, что перебираются все файлы зависимостей из
levels
, и собираются все зависимости, гдеtech
равна указанной в конфиге технологииsourceTech
. Из этих собранных зависимостей собираетсяbemdecl.js
файл, который потом используется в цепочке сборкиbemdecl.js -> deps.js -> технология
. Недостаток в том, что так не соберёшь все нужныеcss
, например (как мы делали вbem-techs-core
).@SevInf
includeBefore
не очень понятно. Что именно должно бытьbefore
, то что в списке ниже или то, к чему описываются зависимости? При этомinclude
намекает на необходимость включения.Может, лучше
deps
иpriority
?deps
определяет зависимость от, аpriority
определяет только приоритет включения.Чтобы задать и зависимость, и приоритет, нужно будет определить сущность в двух списках. Может, стоит предусмотреть дополнительное поле
priority
в сущностях, которые указываются вdeps
? И, если зависимость нужна раньше описываемой сущности, выставляем флагpriority: true
. Примерно так сделано вdeps.yaml
вenb
. Но отдельный список будет по-прежнему нужен для описания приоритета без включения зависимости.@SevInf Добавил входной формат в issue description. Норм?
priority
мне тоже не очень нравится, особенно записьpriority: true
с толку сбивает. Может, лучшеplaceFirst
? Неочевидности нет, ясно что то что в списке размещается сначала.high-priority, foremost, primary, essential, important?
@veged в старой переписке предлагал
orderedDeps/unorderedDeps
.замечания к этому варианты возникли такие:
deps.js
и его можно опустить.Еще варианты из переписки: precedingDeps (preDesp) / depsBefore / beforeDeps / priorDeps / aheadDeps / depsAhead (и они же без Deps)
link + linkBefore
@scf2k
preceding
Предложение priority должен иметь цифровое значение (0, 1, 2...10), если он не указан то вычисляется подобно тому как это сделано в
xslt
алгоритм вычисления задокументировать и при необходимости сделать возможным переопределять подобно тому как планируется сделать с правилом наименования.@ilyar что будет означать, например,
{ priority: 4 }
?@ilyar
priority
в XSLT одна из самых сатанинских штук (сразу после "веса" матча) — добавляет слишком много не очевидного и очень багогеннав
{ priority: 4 }
не больше смысла чем в{ priority: 'primary' }
, общий принцип чем большеpriority
тем выше блок.Вероятно, я не до конца понимаю какую задачу решает
priority
, можно несколько кейсов?Возможно будет полезен наш опыт по приоритезации БЭМ-сущностей, для подключения зависимостей в правильном порядке.
Приоритеты БЭМ сущностей
Сразу прошу прощенья, если не в кассу :)
Мы обсуждали и пришли к тому, что
mustDeps
можно заменить наrequire
, аshouldDeps
наexpect
@veged, по-моему,
require
иexpect
— звучат лучше всего предложенного. как смотришь на добавление таких алиасов?ну если все считают, что это понятнее, чем
must
/should
, то я не против ;-)