bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Обсуждение bem-tools 2.0 #3

Open tadatuta opened 11 years ago

tadatuta commented 11 years ago

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

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 будет отдельным пакетом.

tadatuta commented 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). Чтобы каждый модуль сказать что ему нужно, а когда оно подключится (если еще не подключено) — запустить с этими объектами. Стоит вообще об этом думать? Может быть еще какие-то мысли появились?

qfox commented 11 years ago

@tadatuta Похоже, я должен это визуализировать ;-)

tadatuta commented 11 years ago

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 тоже неплохо, но сам по себе из коробки не дает требуемой функциональность ;-(. Поэтому и думаю.

В общем, итого тезисно. Пока не знаю, насколько это будет быстро работать.

Ну и так далее, тому подобное.

А. Ярошевич

qfox commented 11 years ago

Как лучше пробрасывать 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 метода, а все остальное через модули.

SevInf commented 11 years ago

Пара моих мыслей насчет модульности из старой переписки:

У меня есть мысли что более простая система сборки могла бы это все [команды, технологии и ноды] описать понятием task:

  • таск -- это нечто имеющее имя, метод run, и запускающееся командой вида bem task-name. Выполняет произвольный код, может приимать какие-либо аргументы извне.;
  • некоторый стандартный набор тасков и их зависимостей идет уже преднастроенным системой сборки;
  • дополнительные зависимости и таски описываются в make.js;
  • то что раньше назвалось технологией в этой системе было бы просто специализированным видом тасков;
qfox commented 11 years ago

@SevInf В принципе, ок. Только в этом случае мы заранее усложняем таск (технологию) введением обработки опций, либо прослойку обработки опций переносим в ядро. Pros: унифицированный интерфейс, меньше понятий — проще дока, ? Cons: сложнее поддержка, меньше гибкости, все внутренние таски станут видны наружу.

Про скрытие лишнего (последний пункт) — я может быть слишком наивный, но перегруженное АПИ очень сильно повышает порог вхождения. Можно продумать вариант, когда таски будут декларироваться отдельно, прокидываться отдельно, но просто. Некий хелпер для

tasks().forEach(function (task) { defineCommand(task); })
SevInf commented 11 years ago

@zxqfox, правильно ли понял, что таск в этом случае не становится командой, пока мы явно этого не скажем?

qfox commented 11 years ago

@SevInf, предлагаю, чтобы он был виден из кода при декларации, но не при вызове из терминала типа bem task

SevInf commented 11 years ago

@zxqfox, да, согласен.

SevInf commented 11 years ago

Хотелось бы в добавок к модульности в bem-tools.next получить convention over configuration. Типичная структура проекта более-менее устоялось и можно предполагать ее наличие по умолчанию, а именно:

Хотелось бы, чтоб для подобной структуры сборку не надо было конфигурировать. При этом, для подлючение новой библиотеки следующей этой же схеме ограничилось каким-нибудь ключем в конфиге вида {"libraries": ["lib1", "lib2"]} - нужные уровни для библиотеки сами бы включились в процесс сборки бандлов.

qfox commented 11 years ago

@SevInf, вообще, я пытаюсь сделать так, чтобы настройки по умолчанию тоже можно было вынести в отдельный npm-пакет.

Банально, в config.js (или make v3) описываем список пакетов, которые надо подключить. Туда прописываем пакет с нужным неймингом — и радуемся. Надеюсь, что будет несколько заготовок. Можно даже в одном базовом пакете несколько разных рекоммендуемых схем описать. Если не нравится — убираем пакет и описываем ручками уровни, и все остальное. Как именно — пока тоже вопрос. Порядок, при подходе с ym, не должен играть сильного значения, но есть нюансы.

Сейчас я думаю, что информацию про уровни надо собирать по необходимости, но всю. Т.е., условно, отдельно получаем список сущностей, отдельно строим граф, если он требуется, отдельно читаем файлы технологий, и т.д. результаты запоминаем. Чтобы можно было делать примерно так: var граф = взятьУровни().взятьБлоки().filter(выкидываем лишние).reduce(но помним про всех и запускаем таски на нодах) граф.filter(...).делаемМагию()

arikon commented 11 years ago

/cc @diunko @scf2k

qfox commented 11 years ago

@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');
    // ...
  });
});

Уровень, кстати говоря, смешивается с понятием уровня переопределения и мешает вменяемому восприятию действительного. И не надо забывать, что явное лучше неявного ;-(.

SevInf commented 11 years ago

Хотелось бы чтоб для project-stub конфиг условно говоря выглядел как-то так:

bem.usePlugin('default-project-layout');

bem.useBlocksLibrary('bem-core');
bem.useBlocksLibrary('bem-components');

И автоматически предпологалась структура проекта и библиотек описанная выше. При этом возможность сконфигурировать проект по своему все равно остается, возможно в каком-то виде, похожем на текущий.

Это в моем понимании не замена явного поведения неявным, а добавление поведения по умолчанию, при этом использующее уже де-факто принятую схему раскладки файлов в проекте.

Имхо, хороший инструмент не должен требовать тонкой настройки чтобы быть хотя бы минимально полезным. Это не отменяет возможность расширения и кастомизации для опытных пользователей, но снижает порог входа для новичков.

Уровень, кстати говоря, смешивается с понятием уровня переопределения и мешает вменяемому восприятию действительного.

Я тут ни какой новой терминологии не изобретал, понятия "уровень блоков" и "уровень бандлов" есть и сейчас. По факту это и есть простые уровни переопределения.

scf2k commented 11 years ago

Я бы в 2.0 назвал технологии как-то по-другому.

SevInf commented 11 years ago

+1

qfox commented 11 years ago

Я тут ни какой новой терминологии не изобретал, понятия "уровень блоков" и "уровень бандлов" есть и сейчас. По факту это и есть простые уровни переопределения.

@SevInf :cactus: Я про в целом — уровень первого типа, уровень второго типа, уровень библиотеки (наверное, тоже есть?), уровень переопределения и т.д. Все смешалось. Уровни переопределения — это одно, уровни блоков и бандлов — это совсем другое. Уровни переопределения содержат уровни блоков и бандлов. Их бы тоже переосмыслить.

Я бы в 2.0 назвал технологии как-то по-другому.

@SevInf @scf2k таск? технология сейчас объединяет 2 понятия: набор методов для разработчика, и файлы в блоках и бандлах — для пользователя. второе я предварительно назвал реализацией, но тоже не до конца точно. если первое таск — как реализацию назвать?

scf2k commented 11 years ago

Уровни переопределения — это одно, уровни блоков и бандлов — это совсем другое

Уровни переопределения - это уровни переопределения. Уровни блоков и банлов - это все те же уровни переопределения. Просто в зависимости от того что в них лежит (не в бэм терминах, а функциональных) - мы можем обозвать их как-то по-другому. Но они по-прежнему являются уровнями переопределения.

таск? технология сейчас объединяет 2 понятия: набор методов для разработчика, и файлы в блоках и бандлах — для пользователя

Под технологией в данном контексте я понимаю то что пишется в "модуле технологии".

qfox commented 11 years ago

@scf2k А модуль технологии — это .bem/techs/tech? или block/tech? Так или иначе, терминология путает. btw, я думаю, что нет смысла отдавать в технологии интерфейс к уровню. В основном технологии нужны исключительно её файлы. Каким-то больше, каким-то меньше, но только реализации в конкретных блоках. Так можно упростить интерфейс, с которым работает технология: Передавать туда список бэм сущностей (узлов) для проекта (или каждый отдельно), и на выходе иметь результат — бэм-сущность (список результатов для узлов), или 1 результат, или 2 списка (из одной реализации получаем две другие промежуточные, например), etc.

scf2k commented 10 years ago

Мои general мысли на тему "каким мог бы быть 2.0".

Идея реализации ядра. В качестве предложения на обсуждение, я еще не знаю на сколько она хороша и т.д. Пока просто мысль вслух. Есть стек выполненных "задач", в который по завершении задачи кладется ее id. У каждой задачи есть список id, от которых она зависит и не может выполняться до выполнения их всех. Когда в стеке появляется все из списка, задача может выполниться. Звучит похожим на apw, но отличие в отсутствии связей в чистом виде. Что упрощает расставление зависимостей и должно быстрее работать. В apw перелинковка нод плана после каждого изменения arch отжирает немло времени, что становится заметно на крупных проектах с большим количеством нод.

Пока писал предыдущий абзац, появилась альтернативная мысль. Не смотрел подробно в enb, возможно там сделано так. В стек складывать id задачи и промис на результат ее выполнения. Тогда заивсимые задачи получают возможность сделать часть своей работы до выполнения всех зависимостей, когда выполнилась только часть.

qfox commented 10 years ago

@scf2k ура!

Первые 1, 3, 4 пункты согласен полностью. Пункт 2 — сложности с терминологией, но в целом тоже согласен. Нужно понять что нужно и назвать соотв. образом. Последний пункт — прямая передача не нужна и будет только вредить. Но отбирать возможность запрашивать данные через общее апи, или ядро/некий модуль — плохо.

Ядро, я думаю, стоит разделять на несколько модулей. Смысла отдельном сборщике в целом я не вижу, но какой-то опциональный модуль более тонко управлящий сборкой может быть полезен. С ID, если они будут выглядеть как bundle/tech, где bundle (или, лучше, block) это контекст, а запрашиваться она будет через tech — тоже абсолютно согласен. Тут нужны промисы, они сильно упрощают логику в целом.

Учитывая последний абзац — промисы как-то так, как описано тут? https://github.com/bem/bem-talk/issues/5 Вроде бы, в таком виде они могут существовать и код будет выглядеть очень просто, куча пространства для оптимизации, т.к. все асинхронное и декларативное.

voischev commented 10 years ago

Круто!

qfox commented 10 years ago

Дааа, на словах мы Лев Толстой!