Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Обсуждение bem-deps #10

Open
arikon opened this issue Dec 21, 2013 · 20 comments
Open

Обсуждение bem-deps #10

arikon opened this issue Dec 21, 2013 · 20 comments

Comments

@arikon
Copy link

arikon commented Dec 21, 2013

Обязанности 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...)
@SevInf
Copy link

SevInf commented Dec 21, 2013

Раз уж речь о депсах, я бы предложил разделить необходимость подключения зависимости и порядок включения. Как уже замечали, should, must и include: false - непонятная и нелогичная штука. Например:

{
    deps: [
        {block: 'a'},
        {block: 'b'}
    ],

    includeBefore: [
        {block: 'b'},
        {block: 'c'}
    ]
}

@SevInf
Copy link

SevInf commented Dec 21, 2013

Вместо 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, можно придумать более специфичную для нас структуру хранения данных.

@arikon
Copy link
Author

arikon commented Dec 22, 2013

@SevInf Про query() интересно, нужно больше подробностей и примеров использования.

Типовые задачи:

  • получить список зависимостей для сборки js (или любой другой технологии)
  • получить список bemhtml зависимостей для сборки js (собирать для клиента только нужные шаблоны)
  • получить полный список зависимостей для сборки css (к обычным прямым зависимостям добавляются зависимости других технологий от css)

Был недавно ещё топик про то, что при сборке бандла css нужно собирать для всех блоков, а при сборке ie.css нужно некоторые зависимости отменять. Надо подумать, можно ли это выразить.

@SevInf
Copy link

SevInf commented Dec 22, 2013

получить список зависимостей для сборки js (или любой другой технологии)

.query({tech: 'js'});

получить список bemhtml зависимостей для сборки js (собирать для клиента только нужные шаблоны)

.query({tech: {'js': 'bemhtml'}})

получить полный список зависимостей для сборки css (к обычным прямым зависимостям добавляются зависимости других технологий от css)

.query({tech: 'css', full: true}), если я правильно тебя понял.

Был недавно ещё топик про то, что при сборке бандла css нужно собирать для всех блоков, а при сборке ie.css нужно некоторые зависимости отменять. Надо подумать, можно ли это выразить.

Тут пока затрудняюсь хорошо ответить. Возможно, какой-то параметр вроде skip поможет:

.query({tech: 'ie.css', skip: {block: 'noie'}});

@scf2k
Copy link

scf2k commented Dec 22, 2013

получить список bemhtml зависимостей для сборки js (собирать для клиента только нужные шаблоны)
.query({tech: {'js': 'bemhtml'}})

Не смог осмыслить почему так.

@arikon
Copy link
Author

arikon commented Dec 22, 2013

Посмотрел на deps-resolver из enb. Тестов на него нет, jsdoc минимальный, и комментариев по коду нет совсем.

Понять, как оно используется можно из кода технологии deps.js.

Особенности реализации:

  • захардкожено знание про BEViS (view, skin) вперемешку со знанием про БЭМ (block, elem, mods)
  • конструктор на вход получает объект 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).

@arikon
Copy link
Author

arikon commented Dec 22, 2013

@SevInf

Раз уж речь о депсах, я бы предложил разделить необходимость подключения зависимости и порядок включения

includeBefore не очень понятно. Что именно должно быть before, то что в списке ниже или то, к чему описываются зависимости? При этом include намекает на необходимость включения.

Может, лучше deps и priority? deps определяет зависимость от, а priority определяет только приоритет включения.

Чтобы задать и зависимость, и приоритет, нужно будет определить сущность в двух списках. Может, стоит предусмотреть дополнительное поле priority в сущностях, которые указываются в deps? И, если зависимость нужна раньше описываемой сущности, выставляем флаг priority: true. Примерно так сделано в deps.yaml в enb. Но отдельный список будет по-прежнему нужен для описания приоритета без включения зависимости.

@arikon
Copy link
Author

arikon commented Dec 22, 2013

@SevInf Добавил входной формат в issue description. Норм?

@SevInf
Copy link

SevInf commented Dec 23, 2013

priority мне тоже не очень нравится, особенно запись priority: true с толку сбивает. Может, лучше placeFirst? Неочевидности нет, ясно что то что в списке размещается сначала.

@scf2k
Copy link

scf2k commented Dec 23, 2013

priority мне тоже не очень нравится, особенно запись priority: true с толку сбивает. Может, лучше placeFirst? Неочевидности нет, ясно что то что в списке размещается сначала.

high-priority, foremost, primary, essential, important?

@tadatuta
Copy link
Member

@veged в старой переписке предлагал orderedDeps/unorderedDeps.

замечания к этому варианты возникли такие:

  1. не очевидно, почему ordered — это про то, что будет подключено до.
  2. слово deps очевидно из того, что мы пишем это в файле deps.js и его можно опустить.

Еще варианты из переписки:
precedingDeps (preDesp) / depsBefore / beforeDeps / priorDeps / aheadDeps / depsAhead (и они же без Deps)

link + linkBefore

@arikon
Copy link
Author

arikon commented Dec 23, 2013

@scf2k

high-priority, foremost, primary, essential, important

preceding

@ilyar
Copy link

ilyar commented Aug 11, 2014

Предложение priority должен иметь цифровое значение (0, 1, 2...10), если он не указан то вычисляется подобно тому как это сделано в xslt алгоритм вычисления задокументировать и при необходимости сделать возможным переопределять подобно тому как планируется сделать с правилом наименования.

@tadatuta
Copy link
Member

@ilyar что будет означать, например, { priority: 4 }?

@veged
Copy link
Contributor

veged commented Aug 11, 2014

@ilyar priority в XSLT одна из самых сатанинских штук (сразу после "веса" матча) — добавляет слишком много не очевидного и очень багогенна

@ilyar
Copy link

ilyar commented Aug 11, 2014

в { priority: 4 } не больше смысла чем в { priority: 'primary' }, общий принцип чем больше priority тем выше блок.

Вероятно, я не до конца понимаю какую задачу решает priority, можно несколько кейсов?

@bivihoba
Copy link

Возможно будет полезен наш опыт по приоритезации БЭМ-сущностей, для подключения зависимостей в правильном порядке.

Приоритеты БЭМ сущностей

Сразу прошу прощенья, если не в кассу :)

@iamstarkov
Copy link

Мы обсуждали и пришли к тому, что mustDeps можно заменить на require, а shouldDeps на expect

@tadatuta
Copy link
Member

@veged, по-моему, require и expect — звучат лучше всего предложенного.
как смотришь на добавление таких алиасов?

@veged
Copy link
Contributor

veged commented Aug 12, 2014

ну если все считают, что это понятнее, чем must/should, то я не против ;-)

@innabelaya innabelaya removed the tools label May 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants