EN
vithar
vithar
24 декабря 2015

12-13 декабря у нас был хакатон по разработке инструментов БЭМ. Я участвовал в команде переосмысления и разработки прототипа bem-tools, напишу, что у нас получилось.

В нашей команде было 6 человек:

Решили, что bem-tools надо делать по архитектуре «минимальное ядро + плагины». Ядро не умеет ничего, кроме общей обвязки про CLI, поиска локально или глобально установленных пакетов bem-tools-something и запуска указанной пользователем команды.

Собственно, так и получилось. Весь код ядра умещается на один экран и, кажется, развивать тут дальше нечего.

Плагин предоставляет JS API, которое ничего не знает про CLI (файл index.js в корне) и CLI интерфейс (файл cli.js). Это позволяет рассматривать каждый плагин, как отдельный пакет, который можно использовать независимо от всех остальных.

Мы успели сделать минимальные версии bem-tools-init, bem-tools-make, bem-tools-create и bem-tools-find. А так же вспомогательные bem-fs-scheme и bem-config. Миша Баранов делал плагин для IntelliJ IDEA для создания БЭМ-сущностей из интерфейса IDE.

Как это обычно бывает после хакатона, всё в сыром состоянии, использовать в работе это всё пока нельзя, но зато можно успеть повлиять на API и помочь нам с доработками.

Обо всём этом ниже подробнее.

Скачиваем bem-tools:

npm i bem/bem-tools#WIP
bem

Если всё прошло успешно, после запуска bem увидим:

Tools to work with files written using the BEM methodology.
See https://bem.info for more info.


Usage:
  bem [OPTIONS] [ARGS]


Options:
  -h, --help : Help
  -v, --version : Version

Установим команду init:

npm i bem-incubator/bem-tools-init

Запускаем ещё раз bem и видим, что появилась команда init:

Tools to work with files written using the BEM methodology.
See https://bem.info for more info.


Usage:
  bem COMMAND [OPTIONS] [ARGS]
  bem [OPTIONS] [ARGS]

Commands:
  init : Init

Options:
  -h, --help : Help
  -v, --version : Version

Запуск bem init my-test-project создаст my-test-project и в ней файл bemconf.json с содержимым

{
   "root": true
}

Это маркер корня проекта, будет использоваться другими командами для поиска настроек проекта.

Для работы с конфигом сделали простую библиотеку bem-config (https://github.com/bem-incubator/bem-config/) и накидали примерную структуру файла конфигурации.
Файл конфигурации ищется в текущей директории и выше до корня. Используется ближайший найденный, также к нему добавляется ~/.bemconf.json.

Хотим, чтобы команда init была более умной, например, могла помимо пустого проекта создать заготовку по шаблону. Как вариант, клонировала project-stub.
Сейчас это пример минимального плагина, можно использовать его для написания своего.

Следующая не менее минималистичная команда — make:

npm i bem-incubator/bem-tools-make

Просто вызывает enb :)

Ещё мы сделали прототип команды create:

npm i bem-incubator/bem-tools-create

Она поддерживает, как «классический» синтаксис bem-tools:

bem create -b b1 -t css -t js -l .
bem create -b b2 -t css -t js -l .

так и более простой:

bem create {b1,b2}.{css,js}

Есть шаблоны для технологий по умолчанию. Можно задать свои в конфиге, получаемом через bem-config. Они могут быть локальными для уровня, для проекта или браться из конфига пользователя.

Для построения имён БЭМ-сущностей используется bem-naming, для путей на файловой системе — bem-fs-scheme (пока реализована только nested схема, но легко можно добавить другие). И то, и другое можно задать в файле конфигурации.

Есть ещё что доделывать, постепенно доработаем и выпустим в рамках bem-tools 2.0.

Андрей Кузнецов и Илья Исупов написали прототип команды find (https://github.com/bem-incubator/bem-tools-find/), которая позволяет искать БЭМ-сущности и показывать их в разном виде.

Например, нам нужно найти все файлы про модификатор type для блока input:

bem find -b input -m type
/Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_password.bemhtml
/Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_password.bh.js
/Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_search.bemhtml
/Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_search.bh.js

или то же самое, но в виде дерева:

bem find -b input -m type -v tree
tree
└─┬ /Users/vitaly/sites/project-stub/libs/bem-components/common.blocks
  └─┬ input
    └─┬ _type
      ├─┬ password
      │ ├── bemhtml: /Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_password.bemhtml
      │ └── bh.js:   /Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_password.bh.js
      └─┬ search
        ├── bemhtml: /Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_search.bemhtml
        └── bh.js:   /Users/vitaly/sites/project-stub/libs/bem-components/common.blocks/input/_type/input_type_search.bh.js

Миша Баранов делал плагин для Intellij IDEA (WebStorm, PhpStorm, etc), который будет позволять создавать БЭМ-сущности из контекстного меню (https://github.com/bem-incubator/bem-tools-intellj-plugin).

Плагин предоставляет только интерфейсную обвязку для встраивания в контекстное меню и показа диалога пользовательского ввода, а потом всё что ввёл пользователь передаёт bem create, который уже и делает всю основную работу.

Content menu

Dialog

Что же дальше? А дальше --Новый год-- у нас есть хитрый план: довести всё перечисленное до рабочего состояния, покрыть тестами и написать документацию. А потом... не останавливаться на достигнутом, а реализовать ещё bem rm, bem cp, bem mv, а там, глядишь, и сообщество подтянется со своими плагинами. ;)

ilyar
#ilyar
25 декабря 2015

Отличная новость! Спасибо за рассказ.

Недавно открыл для себя проект 24pullrequests подробнее по ссылке http://24pullrequests.com/contributing, там же есть список подобных проектов.
Будет замечательно вынести планы в запросы пометив соответствующими ярлыками (24pullrequests: bug, design, feature, documentation, tests, help-wanted, refactoring, enhancement, beginner) и добавить пакеты в список этих сервисов.

ilyar
#ilyar
3 января 2016

@vithar Плагин предоставляет JS API, которое ничего не знает про CLI (файл index.js в корне) и CLI интерфейс (файл cli.js). Это позволяет рассматривать каждый плагин, как отдельный пакет, который можно использовать независимо от всех остальных.

@tadatuta договорились, что плагины для bem-tools не имеют собственных бинарников и запускаются из CLI только через ядро bem-tools. это экономит на необходимости ставить COA с каждым плагином и избавляет от таких вот проблем. https://github.com/bem-incubator/bem-tools-rm/pull/2#issuecomment-168499953

COA не ставим для плагина, но описываем для плагина опции и аргументы в стиле COA. Получается не явна зависимость? Как плагин может ничего не знать про CLI для которого ему надо быть готовым (опции, аргументы и справка)?

vithar
#vithar
3 января 2016

index.js provides generic api, cli.js implements COA command, not separate cli tool. See bem-tools-{init, create}.

3 янв. 2016 г., в 17:30, Ilya Rogov notifications@github.com написал(а):

@vithar Плагин предоставляет JS API, которое ничего не знает про CLI (файл index.js в корне) и CLI интерфейс (файл cli.js). Это позволяет рассматривать каждый плагин, как отдельный пакет, который можно использовать независимо от всех остальных.

@tadatuta договорились, что плагины для bem-tools не имеют собственных бинарников и запускаются из CLI только через ядро bem-tools. это экономит на необходимости ставить COA с каждым плагином и избавляет от таких вот проблем. bem-incubator/bem-tools-rm#2 (comment)

COA не ставим для плагина, но описываем для плагина опции и аргументы в стиле COA. Получается не явна зависимость? Как плагин может ничего не знать про CLI для которого ему надо быть готовым (опции, аргументы и справка)?


Reply to this email directly or view it on GitHub.

tadatuta
#tadatuta
3 января 2016

@ilyar Виталя так и написал: JS API не знает, а cli.js, разумеется, знает.
При этом JS API полностью самодостаточный и может использоваться сам по себе, все зависимости должны ставиться из коробки. А CLI предполагает, что у пользователя установлено ядро bem-tools и без него работать не может.

Это вполне соответствует общепринятой схеме. Например, генераторы для yo не будут работать без самого yo.

blond
#blond
3 января 2016

@tadatuta, а версия coa и bem-tools где-то фиксируется? Если выйдет мажорная версия bem-tools или bem-tools заиспользует мажорную версию coa, плагин же сломается?

А ещё не нашёл в плагинах тестов для CLI. Ничего не придумали?

tadatuta
#tadatuta
3 января 2016

версия coa и bem-tools где-то фиксируется?

Как фиксировать версии пока не придумал, но, пожалуй, стоит заворачивать все CLI-плагины в какую-нибудь оберточку на случай апдейта/замены COA.

А ещё не нашёл в плагинах тестов для CLI. Ничего не придумали?

Думаю, что тут все просто — ставить bem-tools в devDependencies и использовать в тестах.

ilyar
#ilyar
4 января 2016

Как фиксировать версии пока не придумал, но, пожалуй, стоит заворачивать все CLI-плагины в какую-нибудь оберточку на случай апдейта/замены COA.

Может быть так peerDependencies

{
  "name": "bem-tools-bar",
  "version": "1.0.0",
  "peerDependencies": {
    "bem-tools": "2.x"
  }
}
blond
#blond
4 января 2016

Может быть так peerDependencies

Использовать peerDependencies будет не рационально для плагинов, которые могут работать через JS API, а не через CLI.

ilyar
#ilyar
4 января 2016

Соглашусь, тогда в optionalDependencies и версия должна совпадать с devDependencies потому что будет проверена в тестах.

{
  "name": "bem-tools-bar",
  "version": "1.0.0",
  "devDependencies": {
    "bem-tools": "2.x"
  },
  "optionalDependencies": {
    "bem-tools": "2.x"
  }
}
zxqfox
#zxqfox
9 января 2016

Разве optional не для нативных опциональных зависимостей, которые могут не собраться под какую-то платформу?

ilyar
#ilyar
17 января 2016

@zxqfox так, но не исключительно так, потому что optionalDependencies зависимость которая не зафейлит установку зависимостей, если не будет возможности ее установить и обработка ее отсутствия лежит в ответственности разработчика (вольный перевод документации, поправите если понял не верно https://docs.npmjs.com/files/package.json#optionaldependencies).

К сожалению, как я описал выше использовать все рано не получится. Потому что она будет установлена, если это возможно, а не установить ее можно с клюем --no-optional.

Остается не понятно как описывать зависимость для плагинов от bem-tools, а скорее от COA. Наверное это надо будет решать на уровне bem-tools.