Пока @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. Призываю к голосованию потенциальных авторов команд, технологий, и других плюшек. Каждый голос важен!
/cc @arikon @SevInf @tadatuta @diunko @scf2k
призываю написать более конкретных примеров, чтобы не высасывать API из пальца — в идеале нужно взять несколько существующих кусочков кода и подумать как их удобнее было бы написать в виде плагинов
Как во вариантах 2 и 3 подключить одновременно и технологию, и уровень?
@SevInf Смысл в том, что уровень никак не коррелирует с технологией. Тот факт, что одно находится в другом — не дает им связи с точки зрения бэм-предметной области. Технологии (алгоритмы) и их реализации (объекты) относятся к узлам (блокам и бандлам), но не к уровням. Уровни, с другой стороны, контейнеры для всего этого и нужны исключительно для предварительной настройки проекта. Сейчас это звучит так: для бандла Х используем сумму множеств технологий уровней А Б В, сумму множеств блоков уровней Г Д Е, и т.д. В итоге, работать приходится с плоским списком технологий, блоков, и их реализаций. Ну и отдельно deps, конечно, который делает из списка граф, описывая связи узлов между собой. Проблема алиасов, в таком случае, сводится к проблеме переименования технологий. Остальное автоматически реализуется платформой.
@veged Основной вопрос в том, стоит ли делать загрузку проекта при инициализации платформы асинхронно, или будем надеятся на скорость жестких дисков. Из асинхронного не сложно звать синхронные алгоритмы. Обратное неверно.
@SevInf но если очень надо, то самое простое:
@veged Поделись своими мыслями, чтоли, хотя бы переварю.
Посмотрел enb, в make файле https://github.com/mdevils/project-stub/blob/master/.bem/enb-make.js описывается все, но уровни находятся в технологиях, я не поддерживаю такой подход, потому что: технология для блоков — это некоторое преобразование, а не команда или процедура, в неё какие-то данные входят, естественно бэм ориентированные, и чаще всего — одноименные, и на выходе получается какой-то результат. Когда как уровни (
bem-levels
) — это суть служебная библиотека, позволяющая расширить 1 уровень на много. В enb она подключается как технология, т.е. технология там слишком жирное понятие, с которым будет сложно работать. Нужна золотая середина.@zxqfox конечно всё нужно делать асинхронным! ;-)
@zxqfox Я поддержу @veged'a в том, что API лучше рассматривать на реальных примерах. Есть уже достаточно большое количество задач, которые как-то решены в
bem make
иenb
. Можно брать оттуда и представлять в новом API. Сразу будут видны преимущества и промахи.