Войти с помощью github

Здесь собираем варианты API TechBuilder, выбираем наиболее подходящий.

Пока @veged не закрыл песочницу, скажите, как лучше подключать плагины?


Вариант нумер 1 с ручным переопределением, доопределением некоего объекта BEM. Плагин выглядит так:

module.exports = function (BEM) {
  // пишем команду
  BEM.command.cmd()
    .opt()....end()
    .act(function () { ... });
  // работаем с внуренностями
  BEM.levelManager.get('somelevel').doSomething();
  BEM.techManager.get('uberstrings').makeMeHappy();
  // добавляем какой-то метод и объект
  BEM.mySpecialMethod = function ... ;
  BEM.superContainer = { ... };
};

Вариант нумер 2 с предоставлением интерфейса с ym. В этом случае можно даже зафризить объект, чтобы не было желания работать через "глобальный" объект BEM. Т.е. некий jail.

module.exports = function (BEM) {
  // отдаем объект coa, который подкоманда abc
  BEM.defineCmd('abc')
    // тут лучше оставить как есть, решение хорошее
    .opt()...end().act(...);
  // внутренности закрываем
  BEM.requireLevel(['somelevel'], function (somelevel) {
    somelevel.doSomething();
  });
  BEM.requireTech(['uberstrings'], function (uberstrings) {
    uberstrings.makeMeHappy();
  });
  // добавляем какой-то метод
  BEM.define('bem', function (provide, bem) {
    bem.mySpecialMethod = ...;
    bem.superContainer = { ... };
    provide(bem);
  });
};

Вариант нумер 3. Как 2, но через "промисы":

module.exports = function (BEM) {
  BEM.defineCmd...
  // fail навешиваем в BEM.requireLevel, если он не найдется.
  BEM.requireLevel('somelevel').thenCall('doSomething');
  BEM.requireTech('uberstrings').then(function (uberstrings) {
    uberstrings.makeMeBoring();
  });
  BEM // или просто define
    .defineProperty('mySpecialMethod', function ...)
    .defineProperty('...');
});

"Зачем нам этот огород?" — спросите вы. Все просто. Менеджер уровней и уровни, которые есть в bt1.0, предлагается спрятать в пакете bem-levels, допилить, и подключать как-то так:

module.exports = function (BEM) {
  require(level), require(levels), ...
  var levelManager = new ...
  BEM.define('levels', function () {
  });
  BEM.on('ready', function () {
    levelManager.cd( BEM.require('config').cwd() );
  });
}

Аналогичным образом, еще до bem-levels, подключится bem-config, и скажет, что он определяет config. За ними bem-deps, bem-make, build, decl, etc. Все эти команды должны иметь 1 понятный интерфейс, чтобы работать с бэм-предметной областью, а не js-объектами, методами, магией.


p.s. Мне кажется, тут всем нравится api у coa. Можно выкинуть пачку методов для каждого define*, примерно как в 3. Фактически, через плагины нужно будет работать с уровнями, технологиями, командами. Последние две можно описать тасками (или, как минимум, наследоваться от него). Таким образом, получится команда — coa, технология и уровень — какое-то api. Похожим образом сделано в enb: defineНечто(...).настройка1(...).настройка2(...).etc().


p.p.s. Призываю к голосованию потенциальных авторов команд, технологий, и других плюшек. Каждый голос важен!

Конспект встречи Арикона с Лешей Ярошевичем

bem-tools 2.0 — это модульная штука, где ядро — это небольшая программа, использующая COA и для которой можно писать библиотеки.

Все, что относится к командам и АПИ реализуется в виде АПИ.

Уже сейчас с командами сделано, так, что команды можно расширять. Это сделано за счет COA.

Текущее АПИ нужно выносить в отдельные модули. Все команды реализуются в виде отдельных пакетов с экспортируемой функцией, которая на вход получает определенный контекст.

Но как писать эти команды? Копипастить код из текущих bem-tools плохо, т.к. будет много копипаста. Так что нужно вынести куда-то общебэмовую функциональность:

  • bem-config, который умеет читать common-js модуль. Когда программе нужна какая-то настройка, она дергает функцию из конфига (у нее зовется коллбек).
  • Уровни (bem-levels)
    • чтение конфигов
    • интроспеция
    • создание уровня
  • deps (bem-deps)
    • stub
    • parse
    • Deps
    • merge
    • intersect
    • substruct

Служебное низкоуровневое API (bem-util):

  • map
  • reduce
  • translate
  • create (new)

Build берет на вход декларацию (список) и технологию, а на выходе получается как правильно одна сущность — reduce (получает размеченный список сущности, у которых уже есть технология).

translate — это часть bem create, которая из одного файла технологии получает файл в новой технологии.

В bem-tools 2.0 хочется писать технологии не для команд bem create/ bem build, а технологии для сборки. Они будут работать по-разному в зависимости от необходимой собираемой технологии и вызывать внутри себя bem reduce, bem translate, etc.

bem-sets — это форк bem-pr, который отличается по интрефейсу, т.к. служебные библиотеки нужно подключать как npm-модули. Теперь bem-sets расширяются для сборки документации.

bem map — на входе несколько уровней и декларацию, а на выходе не одна сущность, а пачка значений. Пришедший набор в декларации возвращается таким же набором, но как-то трансформированным. Нарпимер, был были common.blocks + desktop.blocks и в результате examples собираются смерженными по специальным правилам.

taffyDB (?)

Пакет bem-tools по зависимостям тянет стандартные модули.

bem make будет отдельным пакетом.