#Как устроен пакет
Пакет (в панели — «решение») — устанавливаемая единица функциональности. Одним нажатием он приносит на сайт справочники, модули, вёрстку, маршруты, права, пункты меню и обработчики событий.
Пакет — это не папка с файлами, которую надо куда-то положить. Это манифест — описание того, что должно появиться на сайте, — плюс, если нужно, файлы с логикой.
#Из чего состоит
packages/e-commerce/
manifest.json обязателен — описание решения
src/ логика: обработчики маршрутов и событий
README.mdБольшинству решений хватает одного manifest.json. Решения «Портфолио»,
«Отзывы», «Вопросы и ответы», «Блок» — это только манифест: справочник,
модуль и вёрстка, без единой строки кода.
#Манифест целиком
{
"name": "Формы",
"code": "form",
"version": "1.9.0",
"description": "Конструктор форм: поля, обязательность, действия после отправки.",
"author": "Wacis",
"core_version": ">=1.0.0",
"dependencies": [],
"dictionaries": [ … ],
"modules": [ … ],
"routes": [ … ],
"permissions": [ … ],
"admin_menu": [ … ],
"listeners": { … },
"assets": [ … ]
}| Ключ | Что описывает |
|---|---|
code | имя решения: латиница, цифры, дефис. Точка нельзя |
version | ровно три числа: 1.9.0. Растить при каждой выкладке |
core_version | ограничение по версии ядра — со знаком |
dependencies | коды решений, без которых это не работает |
dictionaries | справочники и их поля |
modules | модули и их вёрстка |
routes | адреса, которые решение обрабатывает |
permissions | права доступа |
admin_menu | свои пункты меню панели |
listeners | подписки на события |
assets | файлы стилей и скриптов |
core_version без знака означает точное совпадение: "1.0.0"
читается как «работает ровно на ядре 1.0.0», и решение не встанет ни на
одно сегодняшнее. Почти всегда имеется в виду ">=1.0.0".
Подробный разбор каждого ключа — Манифест по частям.
#Что делает установщик
По шагам, в этом порядке:
- читает и проверяет манифест;
- сверяет
core_versionс версией ядра сайта; - проверяет
dependencies— недостающие ставит первыми; - накатывает миграции решения;
- заводит справочники и их поля;
- вторым проходом связывает поля-выборки со справочниками;
- заводит модули с вёрсткой — в двух копиях: рабочей и исходной;
- регистрирует маршруты;
- регистрирует права;
- добавляет пункты меню;
- подключает слушателей событий;
- записывает установленную версию;
- включает решение.
На любом шаге может случиться отказ — тогда всё сделанное отменяется в
обратном порядке. Это не общие слова: установка делает CREATE TABLE,
а его нельзя откатить обычной транзакцией базы, поэтому установщик ведёт
свой список сделанного и обратные действия к нему.
#Что установщик делает бережно
Три правила, о которые чаще всего спотыкаются авторы решений.
Чужой справочник не переписывается. Если справочник с таким именем уже есть, решение его не трогает — но недостающие поля добавляет. Иначе решение вставало бы «успешно», а его блок рисовал пустоту.
Тип поля молча не меняется. Разошёлся тип у существующего поля —
меняют, только если хранилище то же (Текст → Выбор). Иначе
предупреждают и не трогают: превращение текста в число обнулило бы часть
значений.
Примеры кладутся только в свой справочник. В чужой — никогда: подмешать своё к чужому значит завести человеку записи, которых он не заводил.
#Что даёт связка решений
Решения соединяются не прямыми вызовами, а событиями. Так устроены
crm-form, crm-ecommerce, crm-task-manager:
Формы → событие form.submitted
CRM и формы → слушает form.submitted → создаёт заявку
CRM → событие crm.lead.created
Задачи по CRM → слушает crm.lead.created → создаёт задачуПоэтому «Формы» работают без CRM, а CRM — без задач. Ставите связку — появляется связь; снимаете — остальное продолжает работать.
Подробно — События.
#Дальше
- Манифест по частям — каждый ключ с примерами.
- События — список событий и как подписаться.
- Свой пакет — как собрать решение с нуля.
#Что чаще всего идёт не так
«Решение поставилось, а его блок пустой». Модуль решения читает справочник, в котором нет нужных полей: справочник с таким именем уже существовал, и установщик его не переписывал. Посмотрите отчёт установки — там сказано, какие поля были добавлены, а какие пропущены из-за расхождения типов.
«Установка отказала: „Модулю X нужен справочник Y, а его нет“». В манифесте модуль объявлен раньше своего справочника либо имя справочника написано с ошибкой. Справочники заводятся до модулей, но только те, что перечислены в этом же манифесте.
«Решение не встаёт: не подходит версия ядра». В core_version
записано точное число вместо ограничения. Нужно ">=1.0.0", а не
"1.0.0".
«Сняли решение — пропали данные». Значит снимали с отметкой «Удалить и справочники с содержимым». Обычное снятие данные оставляет.