docs: фреймворком приложения выбран Vue 3 с роутером 5 и сборкой Vite
- заведены записка разведки docs/research/spa-framework.md со сравнением Svelte, Vue и React на одном экране и решение ADR-2026-08-11-spa-on-vue - docs/conventions/web-ui.md переписан под Vue: компоненты, маршруты, состояние, обращение к API и показ ошибок - закрыт вопрос «Приложение» в docs/architecture.md, уточнена задача spa-skeleton
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# Приложение пишем на Vue, а Node входит в гейт и в образ
|
||||
|
||||
- **Дата:** 2026-08-11
|
||||
- **Источник:** [../research/spa-framework.md](../research/spa-framework.md) —
|
||||
записка разведки `spa-framework-choice`
|
||||
|
||||
## Решение
|
||||
|
||||
Приложение пишем на **Vue 3** с роутером пятой версии и собираем **Vite** в
|
||||
статику, которую бинарник вшивает через `go:embed` и раздаёт сам. Маршруты
|
||||
задаём своей таблицей через `createRouter`; сборочную надстройку роутера под
|
||||
маршруты по файлам не включаем.
|
||||
|
||||
Вместе с этим в проект входит **шаг сборки статики**: Node и `npm` становятся
|
||||
нужны на машине разработчика, отдельным шагом в `task gate` и слоем сборки в
|
||||
`Dockerfile`.
|
||||
|
||||
Это два решения, а не одно, но принимаются они вместе: шаг сборки появляется при
|
||||
любом из трёх кандидатов, и отдельно от выбора фреймворка его обсуждать не о чем.
|
||||
|
||||
## Почему Vue
|
||||
|
||||
Разведка мерила три кандидата на одном и том же экране и нашла единственное
|
||||
различие, которое расходится в разы:
|
||||
|
||||
> Различает единственное — **размер того, что скачивает телефон**, и он
|
||||
> расходится вчетверо.
|
||||
|
||||
Вшивание в бинарник, цена шага сборки в гейте и установка на телефон у всех трёх
|
||||
оказались одинаковыми и потому ничего не решают.
|
||||
|
||||
По размеру Vue стоит посередине — 33 326 Б на четыре экрана против 17 314 у
|
||||
Svelte и 72 402 у React. Выбран он не по этому числу, а по устойчивости
|
||||
экосистемы, и оба отвергнутых кандидата отвергнуты с названной ценой:
|
||||
|
||||
> **Svelte** — легче Vue вдвое, но своего роутера не имеет, а тот, что есть,
|
||||
> держит один человек. Владелец выбрал экосистему, которая переживёт проект, а не
|
||||
> минимальный размер: 33 КБ на телефоне не отличаются от 17 КБ на глаз, а
|
||||
> брошенная зависимость отличается.
|
||||
>
|
||||
> **React** — вчетверо тяжелее Svelte и вдвое тяжелее Vue, а взамен даёт
|
||||
> экосистему, которой приложению на четыре экрана не на что потратиться.
|
||||
|
||||
Роутер берём пятой версии, а не четвёртой, по тому же доводу: она стабильна с
|
||||
29 января 2026 и несёт метку `latest`, то есть чинить будут её, а не
|
||||
предшественницу. Её сборочная надстройка добавляет 34 пакета в установку, и это
|
||||
принятая цена; на собранный файл она не влияет и необязательна.
|
||||
|
||||
## Почему это ADR
|
||||
|
||||
Запись проходит триггер **дорогим откатом**: переход на другой фреймворк
|
||||
переписывает все экраны разом, а не один файл. Шаг сборки сюда же — он меняет
|
||||
требования к машине разработчика и к образу, и снять его потом можно только
|
||||
вместе с приложением.
|
||||
|
||||
Прежнего решения запись не пересматривает: htmx был снят решением о SPA от
|
||||
2026-08-10, до заведения этого журнала, и парного статуса «заменено на» ставить
|
||||
нечему.
|
||||
|
||||
## Последствия
|
||||
|
||||
- `+` разметка отделена от кода однофайловым компонентом, а роутер и хранилище
|
||||
состояния идут из тех же рук, что и сам фреймворк: третьей библиотеки под них
|
||||
заводить не нужно.
|
||||
- `+` собранная статика — три файла и значок, поэтому `go:embed` берёт каталог
|
||||
обычной строкой, а бинарник остаётся самодостаточным.
|
||||
- `−` **гейт перестаёт зависеть только от Go.** Красный шаг сборки статики
|
||||
становится таким же поводом остановиться, как красный `go build`, а машина
|
||||
разработчика получает второе требуемое окружение сверх `ffmpeg`.
|
||||
- `−` **в образ добавляется слой Node** ради шага, результат которого — три
|
||||
файла; насколько дольше собирается образ и насколько тяжелеет, не замерялось.
|
||||
- `−` в проект приходит `node_modules` на 92 МБ и 84 пакета, за которыми надо
|
||||
следить отдельно от зависимостей Go: `gitleaks` и `golangci-lint` про них
|
||||
ничего не знают.
|
||||
- `−` приложение весит 33 КБ там, где на Svelte весило бы 17. Разница куплена
|
||||
сознательно и обратно не отыгрывается.
|
||||
Reference in New Issue
Block a user