Skip to content

Instantly share code, notes, and snippets.

@qfox
Created October 5, 2017 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qfox/bb5720e20b9d8b3ac95ff950a4cb7ead to your computer and use it in GitHub Desktop.
Save qfox/bb5720e20b9d8b3ac95ff950a4cb7ead to your computer and use it in GitHub Desktop.
ffs.deps.js
// Узел содержит значение с маской и связи. Формат узла:
{
scope: {block: ?String, elem: ?String},
block: ?String,
elems: ?Array<{
scope: {block: ?String, elem: ?String},
elem: ?String,
mods: ?Object<String, String[]>,
shouldDeps: ?Array,
mustDeps: ?Array
}>,
mods: ?Object<String, String[]>,
shouldDeps: ?Array,
mustDeps: ?Array
};
В результат раскрытия маски попападают сущности, которые явно
указаны в полях корневого объекта и объектов в массиве
поля elems.
При наполнении контекстом используем поля объектов scope
в порядке от узла к корню. При выходе за границы узла используем
родительский контекст.
{block: 'b', elems: 'e'} → [{block: 'b'}, {block: 'b', elem: 'e'}]
{scope: {block: 'b'}, elems: 'e'} → [{block: 'b', elem: 'e'}]
{scope: {block: 'b', elem: 'e'}, mods: {a: 1}}
→ [{block: 'b', elem: 'e', modName: 'a', modVal: '1'}]
{scope: {block: 'b', elem: 'e'}, block: 'b', mods: {a: 1}} →
[{block: 'b'}, {block: 'b', elem: 'e', mod: 'a', val: '1'}]
{scope: {block: 'b'}, mods: {a: 1}, elems: [{elem: 'e', mods: {a: 1}}]} →
Хочу только модификаторы блока и элементов
{scope: 'b', mods: {a: 1}, elems: [{scope: 'e', mods: {a: 1}}]} →
Хочу только модификаторы элемента
{scope: {block: 'b', elem: 'e'}, mods: {a: 1}}
b__ww.deps.js
{scope: {block: 'b', elem: 'ww'}, elems: [{elem: 'e', mods: {a: 1}}]}
{elems: [{elem: 'e', mods: {a: 1}}]}
{elems: 'e', mods: {m: ['v']}} → [{elem: 'e'}, {elem: 'e', modName: 'm', modVal: 'v'}]
{scope: {mod: 'm'}, vals: ['a', 'b', 'c']}
{elems: ['asd', 'zxc']} → [{elem: 'asd'}, {elem: 'zxc'}]
b.deps.js
({
block: 'c',
shouldDeps: {block: 'c', elems: ['a', 'b']}
});
({
shouldDeps: {elems: ['a', 'b']}
});
{
block: 'b',
elem: undefined,
mod: 'a',
val: 'b',
elems: [
{
elem: 'e',
mods: {
m: ['v', 'v2'],
m2: ['v', 'v2']
}
},
'e2',
'e3'
]
}
b_m.deps.js
b_m_v.deps.js
c_theme.deps.js:
{ shouldDeps: [{val: 'islands'}, {val: 'normal'}] }
c_theme_islands
c_theme_normal
c.deps.js
{ shouldDeps: {mod: 'theme', val: true}}
[
{block: 'b'},
{block: 'b', elem: ['e', 'e2'], mods: {a: 1}}, — запретить
{block: 'b', elem: 'e', mods: {a: 1}}, — норм
{block: 'b', elem: ['e', 'e2']}, — норм
{block: 'b', mods: {a: 1}}, — норм
{block: 'b', elem: 'e2'},
{block: 'b', elem: 'e3'},
{block: 'b', mod: 'm', val: 'v'},
{block: 'b', mod: 'm', val: 'v2'},
{block: 'b', mod: 'm2', val: 'v'},
{block: 'b', mod: 'm2', val: 'v2'},
{block: 'b', elem: 'e', mod: 'm', val: 'v'},
{block: 'b', elem: 'e', mod: 'm', val: 'v2'},
{block: 'b', elem: 'e', mod: 'm2', val: 'v'},
{block: 'b', elem: 'e', mod: 'm2', val: 'v2'}
]
## Общий алгоритм
- построение графа
- walkerом составляем список всех файлов
- передаем настройки уровней со схемами именования/вложенности (bem-config) и набор уровней для прохода (массив строк)
- получаем неупорядоченный поток объектов, описывающий файл и тенорок, к которому он относится:
`{level: String, path: String, entity: BemEntityName, tech: String}`
- схемы содержат алгоритм обхода уровня и влияют на то, какие файлы вернутся
- из общего потока файлов оставляем только файлы описания зависимостей (далее ФОЗ)
- из каждого ФОЗ получаем нормализованный список зависимостей
- чтение и нормализация ФОЗ происходит с помощью обработчика для нужного формата
- итоговый формат: `Array<{vertex: {entity, tech}, dependOn: {entity, tech}, ordered}>`
- строим граф по всем полученным связям между сущностями используя bem-graph
- работаем с графом
- получаем упорядоченный набор «тенорков» для сборки по декларации и технологии для сборки бандлов
- по нему получаем упорядоченный набор файлов сортированный в соответствии с уровнями переопределения
- передаем всё в руки пользователя
## Обработчик формата `new-deps.js`
- Читаем и эвалим файл в JS-объект в формате deps.js
- Валидируем формат (можно отключить)
- Нормализуем синтаксис (приводим к формату `DepsCollection`)
- Нормализуем в структуру дерева
- Заворачиваем содержимое файлов в корневой узел `{shouldDeps: …}`
- Нормализуем структуру связей для каждого узла, начиная с корневого: трансформируем единичные значения shouldDeps/mustDeps в массивы, для каждого нестрокового элемента массива повторяем.
- Делаем из дерева неупорядоченный плоский список
- Нормализуем синтаксис узлов в полную форму (`{block: ?String, elem: ?ElemEntity[], elems: ?ElemEntity[], mod: ?String, val: ?String, mods: ?Object})` — результатом является дерево нормализованных масок.
- Раскрываем маски тенорков (`[{block: ?String, elem: ?String, modName: ?String, modVal: ?String}]`) — получаем дерево массивов тенорков *3.
- Перестраиваем дерево путем разделения массивов тенорков в узле на отдельные узлы с сохранением зависимостей (shouldDeps, mustDeps). Декартово произведение массива тенорков на массивы зависимостей.
- Используя контекст файла в качестве корневого, рекурскивно наполняем каждый узел контекстом:
- На вход получаем родительский и текущий узлы.
- Наполняем поле tech, если его нет в узле, но есть в родителе.
- Проверяем в узле поле block — значит узел полный, выходим, иначе — наполняем поле block в узле.
- Проверяем в узле поле elem, если есть — выходим, иначе — наполняем поле elem в узле.
- Формируем список зависимостей в итоговом формате. Добавляем зависимость для каждого узла (тенорка) в результирующий плоский список связей между тенорками.
**NB:** ФОЗ (файл описания зависимостей) — сущность файловой системы (файл или папка), содержащая информацию о зависимостях.
**NB:** Рекурсивную нормализованную структуру ФОЗ можно описать следующим образом:
```js
DepsCollection = Array<DepsItem>
DepsItem = {
tech: ?String,
block: ?String,
elem: ?String,
modName: ?String,
modVal: ?String,
shouldDeps: ?DepsCollection,
mustDeps: ?DepsCollection
}
```
**NB:** noDeps RIP.
**NB:** *3 Раскрытие масок на ваше усмотрение.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment