Open tadatuta opened 11 years ago
@zxqfox: Я приведу ряд тезисов, которые надо подтвердить или опровергнуть/поправить.
Структура проектов в общем смысле фиксирована (bundles/bundle/blocks/block, blocks/block, etc.), за исключением **/.bem. Собираемые сущности: узел (бандл/блок), реализация технологии. Служебные сущности: уровень, технология. [понятия технологий несколько смешаны, говоря реализация я буду подразуменвать css, bemhtml, bemjson файлы самих блоков, говоря технология — уникальную алгоритмическую составляющую]. Любой проект — направленный граф из узлов и реализаций (далее граф проекта), описываемый в общем случае директорией узла и реализациями. Сборка любой цели работает с подграфом этого графа, получаемого путем несложного преобразования (map, filter, reduce, etc). Например, из графа проекта можно получить подграф для сборки реализации технологии X какого узла, граф из набора реализаций технологий [X,Y,Z], или граф блоков. Filter может выполняться в любом порядке; map, reduce должны выполняться по упорядоченному подграфу относительно цели. Граф проекта должен иметь возможность достраиваться асинхронно по требованию, чтобы не читать весь граф проекта при старте.
bem-tools — платформа для запуска модулей, работающих с bem предметной областью. bem-config — Конфигурация — peer-dep: bem-tools — модуль, предоставляющий API для работы с конфигурациями уровней. Умеет читать любые конфиги, возможно, будет уметь мержить конфиги, но не вдаваясь в подробности самих конфгиов. Т.е. тупой extend. bem-level — Уровень — peer-dep: bem-tools — хранит информацию об именовании и умеет получать плоские списки узлов, реализаций, технологий; предоставляет API для работы с информацией об уровнях.
Каждый уровень через функционал bem-tools провайдит какой-то доп. функционал, усложняет базовый объект BEM (или BEM.api), и подключаемый модуль может требовать какой-то функциональности. Т.е. модули зависят друг от друга, но работают через общий объект из bem-tools. Либо же асинхронно провайдят, как в ym.
Вроде бы, это самое базовое. Я правильно понимаю общую логику?
Открытые вопросы ;-)
С уровнями, в общем случае, какие-то проблемы есть, кроме перегретого интерфейса и расшаривания getConfig? Есть смысл строить граф проекта в рантайме и шарить между остальными пакетами? Или пусть этим исключительно bem-build занимается? Технологиям про это хорошо бы знать, хотя бы иметь возможность выбирать подграф для работы. Есть, наверное? С deps все как-то усложняется. Сейчас deps описывается и в блоках, и в pages, но нужно ли оно в общем случае? Какие задачи он сейчас решает? Если deps описывает зависимости, а bemdecl описывает используемые блоки, может ли одно из другого получаться путем прямого преобразования через reduce? И можно ли избавиться от mustDeps, shouldDeps, и, особенно, noDeps? По ощущениям, должны быть deps, остальное — хаки, но чувствую, что все очень сложно. Думаю, что в идеале надо строить bem модули, используя интерфейс как ym (или саму ym). Чтобы каждый модуль сказать что ему нужно, а когда оно подключится (если еще не подключено) — запустить с этими объектами. Стоит вообще об этом думать? Может быть еще какие-то мысли появились?
@tadatuta Похоже, я должен это визуализировать ;-)
11.11.2013, 01:15, "Alex Yaroshevich" qfox@ya.ru:
Sergey Belov пишет:
Структура проектов в общем смысле фиксирована (bundles/bundle/blocks/block, blocks/block, etc.), за исключением **/.bem.
В общем случае структура проекта такая, как описано здесь: http://clubs.ya.ru/bem/replies.xml?item_no=2049
С точностью до того, что подключаемые библиотеки сейчас отдельно и не по этой схеме в libs. Кажется, что эта структура сейчас работает, и отходить от неё не стоит.
Если есть сомнения в этом — давайте обсуждать. Я, честно говоря, не вижу разницы между .blocks и .bundles, равно как и между .blocks/ и .bundles/ Т.е., вещи это конечно разные, но не с точки зрения проекта или сборки. Просто в одном месте лежат исходники блоков, в другой — бандлов, но сборка их (узлов), на мой взгляд, идентична — вся разница в наборе технологий. В блоках мы запускаем всякие less, bemhtml, coffeescript, а в бандлах мы запускаем bemtree, bemjson/bemdecl, borschik, csso, uglifyjs, etc. Может быть есть какие-то подводные камни? Но с точки зрения того, как я это вижу — множество/граф через
трансформацию
меняет состояние, при необходимости постфактум пишет результат на диск, и отдает результат тому, кто его запрашивал. Все эти операции находятся на уровне технологий и через апи работают с узлами и их свойствами. Как раз map, reduce, filter тут тоже вполне подходят.Собираемые сущности: узел (бандл/блок), реализация технологии.
Ок. Есть ещё исходные сущности (реализации блоков в технологиях, исходники для сборки бандлов — bemjson.js или декларация, например bemdecl.js). Ну да. В т.ч. и эти сущности описываются как "узлы и реализации", я бы не стал их разделять. Реализация блоков в технологиях — это реализация технологии, исходники для сборки бандлов — имхо, тоже.
Насколько я представляю, с одной стороны:
Любой проект — направленный граф из узлов и реализаций (далее граф проекта), описываемый в общем случае директорией узла и реализациями.
Если это про проект с точки зрения bem make, то похоже. В принципе, если мы работаем с блоками, которые зависят друг от друга, то сложно каким-то другим образом это все смотреть. С точки зрения конечного пользователя (ака fe developer) это будет в основном список блоков, но мы то знаем? Или у меня глаз замылен?
Сборка любой цели работает с подграфом этого графа, получаемого путем несложного преобразования (map, filter, reduce, etc).
Когда я говорил про map, filter, reduce и тп, я имел в виду, что технология, имея на входе декларацию, может пользоваться этими базовыми операциями для получения финального результата своего выполнения. Как угодно их комбинируя. Я вижу, что у технологии должны быть: а) знания о содержмом — о том, с чем именно она работает — отсуда интерфейс про create/mv/rm — да, мы не можем сделать fs.move(old, new) + content.replace(old, new), но если технология знает как её перемещать — то почти всегда сразу можем; б) интерфейс про run (или build), clean (что-то еще?) — build: собираем, сохраняем результат в памяти, чтобы лишний раз не ходить на диск (запись+чтение), записываем постфактум файл, если режим включен (отладка, кеш, whatever); clean: прибираем за собой, если это мы наделали. в) -- я о чем-то тут забыл, но технология сама по себе это алгоритм преобразования одного множества/графа в другое, это лишь сам переход, поэтому, все трансформации описываются именно в них, так что интерфейс не должен быть больше 10-15 методов в сумме; г) и лучше всего, чтобы её тоже можно было перегружать/доописывать в подключаемых модулях — значит, должна быть такая возможность, её предоставляет ym из коробки, если его умудрится красиво подключить.
Пункт (г) в общем случае (перегрузки всего и вся) это краеугольный камень, мне кажется. Если такая возможность будет без черной магии — мы получим очень мощную платформу для разработки фреймворков.
Например, из графа проекта можно получить подграф для сборки реализации технологии X какого узла, граф из набора реализаций технологий [X,Y,Z], или граф блоков. Filter может выполняться в любом порядке; map, reduce должны выполняться по упорядоченному подграфу относительно цели.
Здесь я, честно говоря, не понял. Я выше описал что понимаю под графами
Граф проекта должен иметь возможность достраиваться асинхронно по требованию, чтобы не читать весь граф проекта при старте.
В bem make сейчас так, да. В enb все цели генерируются на старте (и на рядовых проектов это очень быстро). Так что здесь вопрос открытый. У меня есть стойкое ощущение, что разницы между "читаем все" и "дочитываем по необходимости" на небольших проектах быть в целом не должно, и дочитывание должно чуть-чуть проигрывать. Но там, где блоков и зависимостей много — чтение всего будет замедлять процесс при сборке единичных целей, придется кешировать, и инвалидировать кеш, etc. И еще, подозреваю, что текущий алгоритм в бэм-тулзах можно оптимизировать, возможно даже не он сам не оптимальный, а его интерфейс, и связь с APW, все в сумме натыкается на какие-то ботлнеки и подлагивает. Честно говоря, конкретно на эту тему пока не готов говорить. Это просто догадки.
bem-config — Конфигурация — peer-dep: bem-tools — модуль, предоставляющий API для работы с конфигурациями уровней. Умеет читать любые конфиги, возможно, будет уметь мержить конфиги, но не вдаваясь в подробности самих конфгиов. Т.е. тупой extend.
Да, сюда можно упаковать общую логику по подключению и чтению конфигов, реализованных в виде CommonJS модулей, экспортирующих функцию. Я бы не добавлял зависимость от bem-tools в этих модулях. Она скорее всего не будет требоваться, но будет мешать. Библиотеки же всегда будет ставиться исключительно рядом с bem-tools? Разве нет? Я не вижу в них смысла при отрыве от bem-tools. Т.е. он может быть и есть, но я пока не вижу.
Каждый уровень через функционал bem-tools провайдит какой-то доп. функционал, усложняет базовый объект BEM (или BEM.api), и подключаемый модуль может требовать какой-то функциональности.
Каждый уровень или каждый модуль? По смыслу модуль. На счёт усложнения базового объекта уверенности нет. Может быть будет достаточно, что каждый модуль подключает свои зависимости самостоятельно. И на вход от управляющей программы (bem-tools) получает общие объекты, вроде логгера, env и конфига (как пример). Да, конечно же модуль. Вот по поводу зависимостей и передачи, как раз, я и хотел отдельно поговорить. Почему я и думаю, что нужно нечто вроде ym, способного это обслуживать и передавать зависимости.
Т.е. модули зависят друг от друга, но работают через общий объект из bem-tools. Либо же асинхронно провайдят, как в ym.
Я бы не стал здесь усложнять. Стандартной модульности node.js должно хватить. Очень много что хочет доопределять и переопределять общую функциональность ;(. Если можно предоставить эту возможность — почему не сделать этого? Вообще, это как царапки, но нет, оно же дает больше, чем забирает. Да, придется разобраться, как работает ym, но если ты хочешь писать плагины — тебе все равно придется разбираться с API, а интерфейс ym, например, очень схож с текущим интерфейсом AMD, кроме того, что в AMD . Его имплементация всем знакома по requirejs. Люди им пользуются, но часто даже не догадываются, что это AMD, а еще есть CommonJS, и т.п. Есть еще require.ensure(...) для асинхронного require, но нам желателен provide и зависимости.
Вроде бы, это самое базовое. Я правильно понимаю общую логику?
Открытые вопросы ;-)
С уровнями, в общем случае, какие-то проблемы есть, кроме перегретого интерфейса и расшаривания getConfig?
getConfig, кажется, на уровнях нигде не используется, кроме списка уровней для сборки. Но правильно этот список указывать в BundleNode.getLevels().
Но может оказаться полезен, если реализовать доопределение глобальных опций, при условии, что они будут действовать на операции только в рамках этого уровня. Да, тот факт, что bem-config должен клеить и предоставлять конфиги в зависимости от уровня — это точно. Только уровни же у нас ниже, т.е. этот функционал, по хорошему, должен перегружаться в bem-level, а сам bem-config должен просто их читать, и уметь, при прямом воздействии, мержить. Звоночек про доопределение.
Есть смысл строить граф проекта в рантайме и шарить между остальными пакетами?
Граф сборки? Вообще, вопрос получился риторический. ATM я не представляю, как без него вообще что-то делать. Это как речная рыба без костей. Информации для работы технологий недостаточно. Но если технология deps будет готовить граф при необходимости — то тут все просто становится. Скажем, технология deps.js провайдит какой-то метод в объект Множество, если этот метод вызывается — запускаются алгоритмы из deps js, и получается объект Граф, который тоже можно перегружать (т.е. его и заранее можно было перегрузить, но появляется он только on-demand).
Или пусть этим исключительно bem-build занимается? Технологиям про это хорошо бы знать, хотя бы иметь возможность выбирать подграф для работы. Есть, наверное?
Со сборкой пока вопрос открытый. Надо отдельно подробней говорить про неё. Ок.
С deps все как-то усложняется. Сейчас deps описывается и в блоках, и в pages, но нужно ли оно в общем случае? Какие задачи он сейчас решает? Если deps описывает зависимости, а bemdecl описывает используемые блоки, может ли одно из другого получаться путем прямого преобразования через reduce? И можно ли избавиться от mustDeps, shouldDeps, и, особенно, noDeps? По ощущениям, должны быть deps, остальное — хаки, но чувствую, что все очень сложно.
deps тема сама по себе сложная, и вызывающая много вопросов. Можно её рассматривать отдельно в контексте сборки, например. А пока считать, что deps есть в текущем виде. В блоках они описывают зависимости этих блоков от других. В бандлах они выполняют роль деклараций для сборки. Вообще, из списка мы можем построить граф? Вроде бы, да, если в списке есть поле parents. Просто берем и собираем, почему нет? Просто эту технологию нужно будет обязательно поместить ДО тех технологий, которым граф уже потребуется. Это можно сделать руками, можно и автоматически. Но это уже зависимости между самими технологиями. Еще один звоночек про необходимость некой модульной структуры внутри экосистемы.
Думаю, что в идеале надо строить bem модули, используя интерфейс как ym (или саму ym). Чтобы каждый модуль сказать что ему нужно, а когда оно подключится (если еще не подключено) — запустить с этими объектами. Стоит вообще об этом думать?
Не думаю, что в мире node.js нужно придумывать свою модульность. Я пока не наталкивался ограничения стандартной модульной системы.
Но если есть конкретные соображения, готов обсудить. Буквально 6 часов назад я натолкнулся на architect. Грузит модули синхронно, но заранее загружает зависимости. Из минусов, если я правильно понял, он не может дописать в старый модуль новую функциональность. Зависимости описываются в package.json npm-модуля в секции plugin. Для новых bem-tools мне хотелось бы нечто между (или вместе) архитекта и ym. Пока думаю, что проще всего запилить на базе ym нечто с требуемым функционалом.
Почему-то мне кажется, что если будет свобода действий в разработке плагинов — работа над бэмтулзами в целом станет проще и приятнее. Достаточно будет описать как писать команды/служебные библиотеки, как его использовать в дальнейшнем, и т.д. — и практически любой сможет писать ЛЮБОЙ требуемый функционал в виде npm модулей, без ожидания когда вольют его PR и т.п. В общем, я проникся этими плагинами, и полностью за. Практически все можно вынести, оставить только клей для этих модулей. Сам клей заменять смысла нет, он просто проклеивает модули, но его интерфейс будет сложно поменять — поэтому хотелось бы универсальный, но простой вариант. CommonJS тоже неплохо, но сам по себе из коробки не дает требуемой функциональность ;-(. Поэтому и думаю.
В общем, итого тезисно. Пока не знаю, насколько это будет быстро работать.
Ну и так далее, тому подобное.
А. Ярошевич
Как лучше пробрасывать npm-пакеты между собой. Интерфейс ym
через общий объект устраивает?
Пришел примерно к такому API.
// simple bem-plugin
module.exports = function (BEM) {
// ym api. first call we instantiating coa command with name
BEM.defineCommand('command', function (coa) {
// using coa interface for blabla command
});
// it's possible to define multiple commands
BEM.defineCommand('foobar', function (coa) {
// creating command foobar
});
BEM.defineCommand('foobar', function (coa) {
// upgrade command foobar
});
BEM.defineCommand('make', function (coa) {
// upgrade command bem make with subcommand bem make magic
coa.cmd('magic')
.act(...);
});
// описываем плагин, который будет загружаться при BEM.require(['deps'], ...)
BEM.define('deps', ['config', 'level'], function (config, level, provide, prevDeps) {
// independent techs namespace, they all works in bem objects space
BEM.defineTech('deps', function (?) { // same for techs
});
});
// and for some else (levels, probably, or something).
BEM.defineSomeElse...
Или BEM.techs.define, BEM.modules.define, BEM.somethingelse, но хочется, чтобы из BEM наружу торчало 2 метода, а все остальное через модули.
Пара моих мыслей насчет модульности из старой переписки:
У меня есть мысли что более простая система сборки могла бы это все [команды, технологии и ноды] описать понятием task:
- таск -- это нечто имеющее имя, метод run, и запускающееся командой вида bem task-name. Выполняет произвольный код, может приимать какие-либо аргументы извне.;
- некоторый стандартный набор тасков и их зависимостей идет уже преднастроенным системой сборки;
- дополнительные зависимости и таски описываются в make.js;
- то что раньше назвалось технологией в этой системе было бы просто специализированным видом тасков;
@SevInf В принципе, ок. Только в этом случае мы заранее усложняем таск (технологию) введением обработки опций, либо прослойку обработки опций переносим в ядро. Pros: унифицированный интерфейс, меньше понятий — проще дока, ? Cons: сложнее поддержка, меньше гибкости, все внутренние таски станут видны наружу.
Про скрытие лишнего (последний пункт) — я может быть слишком наивный, но перегруженное АПИ очень сильно повышает порог вхождения. Можно продумать вариант, когда таски будут декларироваться отдельно, прокидываться отдельно, но просто. Некий хелпер для
tasks().forEach(function (task) { defineCommand(task); })
@zxqfox, правильно ли понял, что таск в этом случае не становится командой, пока мы явно этого не скажем?
@SevInf, предлагаю, чтобы он был виден из кода при декларации, но не при вызове из терминала типа bem task
@zxqfox, да, согласен.
Хотелось бы в добавок к модульности в bem-tools.next получить convention over configuration. Типичная структура проекта более-менее устоялось и можно предполагать ее наличие по умолчанию, а именно:
common
, desktop
, touch
, touch-phone
и touch-pad
. Некоторые уровни опциональны.desktop
- собирается из блоков common
и desktop
touch-phone
- собирается из блоков common
, touch
, touch-phone
touch-pad
- собирается из блоков common
, touch
, touch-pad
Хотелось бы, чтоб для подобной структуры сборку не надо было конфигурировать. При этом, для подлючение новой библиотеки следующей этой же схеме ограничилось каким-нибудь ключем в конфиге вида {"libraries": ["lib1", "lib2"]}
- нужные уровни для библиотеки сами бы включились в процесс сборки бандлов.
@SevInf, вообще, я пытаюсь сделать так, чтобы настройки по умолчанию тоже можно было вынести в отдельный npm-пакет.
Банально, в config.js (или make v3) описываем список пакетов, которые надо подключить. Туда прописываем пакет с нужным неймингом — и радуемся. Надеюсь, что будет несколько заготовок. Можно даже в одном базовом пакете несколько разных рекоммендуемых схем описать. Если не нравится — убираем пакет и описываем ручками уровни, и все остальное. Как именно — пока тоже вопрос. Порядок, при подходе с ym, не должен играть сильного значения, но есть нюансы.
Сейчас я думаю, что информацию про уровни надо собирать по необходимости, но всю. Т.е., условно, отдельно получаем список сущностей, отдельно строим граф, если он требуется, отдельно читаем файлы технологий, и т.д. результаты запоминаем. Чтобы можно было делать примерно так: var граф = взятьУровни().взятьБлоки().filter(выкидываем лишние).reduce(но помним про всех и запускаем таски на нодах) граф.filter(...).делаемМагию()
/cc @diunko @scf2k
@SevInf Т.е. для текущей устоявшейся конфигурации будет где-то (хоть в модуле) написано так. Это ок?
/**
* В bem-levels - декларируем тип уровней, бла бла
* @param {string} name
* @param {string|Array} [dependencies]
*/
defineLevel: function ...
/**
* И у уровня декларируем на что его применять
* @param {string|RegExp|Function|Array} [filter]
*/
useFor?: function (filter) ...
// ...
bem.defineLevel('common', initCommonLevel);
bem.defineLevel('desktop', ['common'], initDesktopLevel);
bem.defineLevel('touch', ['common', 'desktop'], initTouch);
// etc.
bem.ready(function () {
bem.requireLevel(['common', 'desktop', 'touch', ...], function (common, desktop, touch) {
common.useFor('*.common');
desktop.useFor('*.desktop');
touch.useFor('*.touch');
// ...
});
});
Уровень, кстати говоря, смешивается с понятием уровня переопределения и мешает вменяемому восприятию действительного. И не надо забывать, что явное лучше неявного ;-(.
Хотелось бы чтоб для project-stub конфиг условно говоря выглядел как-то так:
bem.usePlugin('default-project-layout');
bem.useBlocksLibrary('bem-core');
bem.useBlocksLibrary('bem-components');
И автоматически предпологалась структура проекта и библиотек описанная выше. При этом возможность сконфигурировать проект по своему все равно остается, возможно в каком-то виде, похожем на текущий.
Это в моем понимании не замена явного поведения неявным, а добавление поведения по умолчанию, при этом использующее уже де-факто принятую схему раскладки файлов в проекте.
Имхо, хороший инструмент не должен требовать тонкой настройки чтобы быть хотя бы минимально полезным. Это не отменяет возможность расширения и кастомизации для опытных пользователей, но снижает порог входа для новичков.
Уровень, кстати говоря, смешивается с понятием уровня переопределения и мешает вменяемому восприятию действительного.
Я тут ни какой новой терминологии не изобретал, понятия "уровень блоков" и "уровень бандлов" есть и сейчас. По факту это и есть простые уровни переопределения.
Я бы в 2.0 назвал технологии как-то по-другому.
+1
Я тут ни какой новой терминологии не изобретал, понятия "уровень блоков" и "уровень бандлов" есть и сейчас. По факту это и есть простые уровни переопределения.
@SevInf :cactus: Я про в целом — уровень первого типа, уровень второго типа, уровень библиотеки (наверное, тоже есть?), уровень переопределения и т.д. Все смешалось. Уровни переопределения — это одно, уровни блоков и бандлов — это совсем другое. Уровни переопределения содержат уровни блоков и бандлов. Их бы тоже переосмыслить.
Я бы в 2.0 назвал технологии как-то по-другому.
@SevInf @scf2k таск? технология сейчас объединяет 2 понятия: набор методов для разработчика, и файлы в блоках и бандлах — для пользователя. второе я предварительно назвал реализацией, но тоже не до конца точно. если первое таск — как реализацию назвать?
Уровни переопределения — это одно, уровни блоков и бандлов — это совсем другое
Уровни переопределения - это уровни переопределения. Уровни блоков и банлов - это все те же уровни переопределения. Просто в зависимости от того что в них лежит (не в бэм терминах, а функциональных) - мы можем обозвать их как-то по-другому. Но они по-прежнему являются уровнями переопределения.
таск? технология сейчас объединяет 2 понятия: набор методов для разработчика, и файлы в блоках и бандлах — для пользователя
Под технологией в данном контексте я понимаю то что пишется в "модуле технологии".
@scf2k А модуль технологии — это .bem/techs/tech? или block/tech? Так или иначе, терминология путает. btw, я думаю, что нет смысла отдавать в технологии интерфейс к уровню. В основном технологии нужны исключительно её файлы. Каким-то больше, каким-то меньше, но только реализации в конкретных блоках. Так можно упростить интерфейс, с которым работает технология: Передавать туда список бэм сущностей (узлов) для проекта (или каждый отдельно), и на выходе иметь результат — бэм-сущность (список результатов для узлов), или 1 результат, или 2 списка (из одной реализации получаем две другие промежуточные, например), etc.
Мои general мысли на тему "каким мог бы быть 2.0".
Идея реализации ядра. В качестве предложения на обсуждение, я еще не знаю на сколько она хороша и т.д. Пока просто мысль вслух. Есть стек выполненных "задач", в который по завершении задачи кладется ее id. У каждой задачи есть список id, от которых она зависит и не может выполняться до выполнения их всех. Когда в стеке появляется все из списка, задача может выполниться. Звучит похожим на apw, но отличие в отсутствии связей в чистом виде. Что упрощает расставление зависимостей и должно быстрее работать. В apw перелинковка нод плана после каждого изменения arch отжирает немло времени, что становится заметно на крупных проектах с большим количеством нод.
Пока писал предыдущий абзац, появилась альтернативная мысль. Не смотрел подробно в enb, возможно там сделано так. В стек складывать id задачи и промис на результат ее выполнения. Тогда заивсимые задачи получают возможность сделать часть своей работы до выполнения всех зависимостей, когда выполнилась только часть.
@scf2k ура!
Первые 1, 3, 4 пункты согласен полностью. Пункт 2 — сложности с терминологией, но в целом тоже согласен. Нужно понять что нужно и назвать соотв. образом. Последний пункт — прямая передача не нужна и будет только вредить. Но отбирать возможность запрашивать данные через общее апи, или ядро/некий модуль — плохо.
Ядро, я думаю, стоит разделять на несколько модулей. Смысла отдельном сборщике в целом я не вижу, но какой-то опциональный модуль более тонко управлящий сборкой может быть полезен. С ID, если они будут выглядеть как bundle/tech
, где bundle
(или, лучше, block
) это контекст, а запрашиваться она будет через tech
— тоже абсолютно согласен. Тут нужны промисы, они сильно упрощают логику в целом.
Учитывая последний абзац — промисы как-то так, как описано тут? https://github.com/bem/bem-talk/issues/5 Вроде бы, в таком виде они могут существовать и код будет выглядеть очень просто, куча пространства для оптимизации, т.к. все асинхронное и декларативное.
Круто!
Дааа, на словах мы Лев Толстой!
Конспект встречи Арикона с Лешей Ярошевичем
bem-tools 2.0 — это модульная штука, где ядро — это небольшая программа, использующая COA и для которой можно писать библиотеки.
Все, что относится к командам и АПИ реализуется в виде АПИ.
Уже сейчас с командами сделано, так, что команды можно расширять. Это сделано за счет COA.
Текущее АПИ нужно выносить в отдельные модули. Все команды реализуются в виде отдельных пакетов с экспортируемой функцией, которая на вход получает определенный контекст.
Но как писать эти команды? Копипастить код из текущих bem-tools плохо, т.к. будет много копипаста. Так что нужно вынести куда-то общебэмовую функциональность:
Служебное низкоуровневое API (bem-util):
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 будет отдельным пакетом.