128 lines
10 KiB
Markdown
128 lines
10 KiB
Markdown
# Конфигурация проекта prescriptions-frontend
|
||
|
||
Документ описывает способы конфигурирования микрофронтенда `prescriptions-frontend` (Module Federation `srx_prescriptions`, экспонирует `./PrescriptionsPage`), его переменные сборки/CI и параметры деплоя.
|
||
|
||
## Способы конфигурирования
|
||
|
||
В отличие от backend-сервисов, у фронтенда **нет рантайм-конфигурации через `.env`**: собранный бандл — статические файлы, которые раздаёт nginx. Всё поведение задаётся **на этапе сборки** одной переменной — `BUILD_ENV`.
|
||
|
||
- `env.js` читает `process.env.BUILD_ENV` и валидирует его против списка `local`/`stage`/`prod`/`contour`/`preprod` (иначе — ошибка сборки `set BUILD_ENV one of ...`);
|
||
- `webpack.config.js` через `DefinePlugin` внедряет глобальные константы `BUILD_ENV` и `STORYBOOK` в бандл;
|
||
- `build.config.js` по `BUILD_ENV` выбирает режим сборки (`mode`/`devtool`);
|
||
- `module/api/hosts.ts` и `module/api/module-hosts.ts` содержат карты хостов по окружениям; SDK (`@sarex-team/sdk-js`) на рантайме выбирает нужный хост по глобальной константе `BUILD_ENV` (по умолчанию `prod`).
|
||
|
||
Отдельного конфиг-файла (yaml/toml) у приложения нет.
|
||
|
||
### Значения `BUILD_ENV`
|
||
|
||
| `BUILD_ENV` | `mode` | `devtool` | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `local` | `development` | `eval-source-map` | Локальная разработка (dev-server, storybook), `httpService` → `original` |
|
||
| `stage` | `development` | `eval-source-map` | Стенд stage |
|
||
| `preprod` | `production` | `source-map` | Предпрод |
|
||
| `prod` | `production` | `source-map` | Прод |
|
||
| `contour` | `production` | `source-map` | Изолированный контур (относительные пути хостов) |
|
||
|
||
## Переменные сборки и CI
|
||
|
||
| Переменная | Где используется | Назначение |
|
||
| --- | --- | --- |
|
||
| `BUILD_ENV` | `env.js`, `webpack.config.js`, `Dockerfile` (ARG), `.gitlab-ci.yml` (`--build-arg`) | Целевое окружение сборки. Обязательна |
|
||
| `NPM_TOKEN` | `.npmrc`, `Dockerfile` (ARG), `.gitlab-ci.yml` (`--build-arg`) | Токен доступа к приватному npm-реестру `nexus.infra.sarex.io` |
|
||
| `STORYBOOK` | `webpack.config.js` (`DefinePlugin`), `module/pages/index.tsx` | Флаг сборки под Storybook (`"true"`/`"false"`) |
|
||
|
||
Cypress-тесты берут учётные данные из `cypress.env.json` (пример — `cypress.env-example.json`): `SRX_LOGIN`, `SRX_PASSWORD`.
|
||
|
||
Версия Node для разработки — `v20.16.0` (`.nvmrc`).
|
||
|
||
## Хосты по окружениям
|
||
|
||
Базовые API-хосты подставляются из `module/api/hosts.ts` по `BUILD_ENV` (детальная разбивка по сервисам — в `ENDPOINTS.md`):
|
||
|
||
| Окружение | Базовый API | Пример (`documentations`) |
|
||
| --- | --- | --- |
|
||
| `local` / `stage` | `https://stage-api.sarex.io` | `https://stage-api.sarex.io/documentations/api/v1` |
|
||
| `preprod` | `https://api.preprod.sarex.io` | `https://api.preprod.sarex.io/documentations/api/v1` |
|
||
| `prod` | `https://api.sarex.io` | `https://api.sarex.io/documentations/api/v1` |
|
||
| `contour` | относительные пути | `/documentations/api/v1` |
|
||
|
||
Удалённый модуль (Module Federation) `documentations` подключается по `module/api/module-hosts.ts` (`remoteEntry.js`).
|
||
|
||
## Запуск и скрипты (`package.json`)
|
||
|
||
| Команда | Назначение |
|
||
| --- | --- |
|
||
| `npm run serve-module` | Dev-server (`webpack.dev.js`, порт `9001`, https, proxy `/api`, `/admin` на `appUrl`), `BUILD_ENV=local` |
|
||
| `npm run storybook` | Storybook (порт `9000`, https), `BUILD_ENV=local` |
|
||
| `npm run start` / `test:dev` | Параллельный запуск serve-module + storybook (+ cypress в `test:dev`) |
|
||
| `npm run build-module` | Продакшн-сборка модуля (`webpack --config webpack.config.js`) |
|
||
| `npm run build-storybook` | Сборка статики Storybook |
|
||
| `npm run cypress:open` | Запуск e2e-тестов Cypress |
|
||
| `npm run lint` / `lint:ts` | Prettier / проверка типов `tsc --noEmit` |
|
||
|
||
## Сборка образа (`Dockerfile`)
|
||
|
||
Двухстадийная сборка:
|
||
|
||
1. `node:15` — установка зависимостей (`npm i --legacy-peer-deps` с `NPM_TOKEN`), `npm run lint`, `BUILD_ENV=$BUILD_ENV npm run build-module` → `/app/dist`;
|
||
2. `nginx:mainline-alpine-otel` — копирование `dist` в `/dist` и конфига `nginx/nginx.conf`.
|
||
|
||
Build-args: `BUILD_ENV`, `NPM_TOKEN`.
|
||
|
||
nginx (`nginx/nginx.conf`) раздаёт статику из `/dist`, отдаёт `/ping` → `{"result": "ok"}` (healthcheck) и запрещает кеширование `/module/remoteEntry.js` (`Cache-Control: no-store`).
|
||
|
||
## CI/CD (`.gitlab-ci.yml`)
|
||
|
||
Пайплайн подключает общие шаблоны `generic/common-ci` (`common-security-scan.yaml`, `universal-pipeline.yaml`, ref `apps-business`). `SERVICE_NAME=prescriptions-frontend`. Окружение переключается по ветке/тегу (`workflow.rules`):
|
||
|
||
| Условие | STAND | NAMESPACE | BUILD_ENV | CHART_VERSION |
|
||
| --- | --- | --- | --- | --- |
|
||
| ветка `stage` | `stage` | `proc` | `stage` | `1.0.0-stage` |
|
||
| ветка `master` | `preprod` | `prescriptions-preprod` | `preprod` | `1.0.0-preprod` |
|
||
| тег (`CI_COMMIT_TAG`) | `production` | `prescriptions-prod` | `prod` | `1.0.0-prod` |
|
||
| merge request | — | — | — | сборка образа отключена (`ENABLE_BUILD_IMAGE=false`) |
|
||
|
||
Деплой параметризуется через `HELM_SET_ARGS` (образ, `global.env`, `commitSha`, `gitlabUri`, `gitlabJobUrl`, `owner`).
|
||
|
||
## Helm-чарт проекта (`.helm`)
|
||
|
||
`Chart.yaml`: зависимость `universal-chart` (`oci://cr.yandex/.../charts`, версия `0.1.7`).
|
||
|
||
`values.yaml` (`universal-chart.services.frontend`):
|
||
|
||
- `deployment.name = prescription-frontend`, `replicaCount = 1`, `port = 80`, `revisionHistoryLimit = 10` (prod — `15`);
|
||
- `image.name = cr.yandex/crp3ccidau046kdj8g9q/prescription-frontend`, `pullPolicy = IfNotPresent`;
|
||
- `service.name = prescriptions-frontend-service`, `type = ClusterIP`, `port/targetPort = 80`;
|
||
- `imagePullSecrets = dockerhub`;
|
||
- probes (`liveness`/`readiness`) на `/ping:80` заданы, но **выключены** (`enabled: false`);
|
||
- `envs: []`, `secretEnvs: []` — переменных окружения контейнеру не передаётся;
|
||
- ресурсы: `requests` `memory 100Mi`, `cpu 100m`.
|
||
|
||
## Инфраструктура (`iac/apps/prescriptions`)
|
||
|
||
Разворачивается через Kustomize. Состав каталога:
|
||
|
||
| Путь | Назначение |
|
||
| --- | --- |
|
||
| `base/namespace.yaml` | Namespace `prescriptions` с `istio-injection: enabled` |
|
||
| `base/deployment.yaml` | Deployment `frontend`, образ `cr.yandex/.../prescriptions-frontend:production_...`, порт `80`, `requests` `cpu 25m`/`memory 100Mi`, `imagePullSecrets: regcred` |
|
||
| `base/service.yaml` | Service `frontend-service`, `ClusterIP`, порт `80` |
|
||
| `base/kustomization.yaml` | Сборка base (namespace + deployment + service) |
|
||
| `yc-k8s-test/` | Оверлей поверх `../base` (патч `replicas.yaml` закомментирован) |
|
||
| `brusnika-prod/`, `brusnika-stage/` | Оверлеи (см. замечание ниже) |
|
||
|
||
## Замечания и потенциальные проблемы
|
||
|
||
- **Оверлеи `brusnika-prod` / `brusnika-stage`** сейчас содержат `HelmRelease` бэкенда `measurements` (namespace `measurements`, образ `documentations`), не относящийся к prescriptions — похоже на копипаст-заготовку, которую нужно заменить на конфигурацию prescriptions-frontend либо удалить.
|
||
- **Два способа описания деплоя**: helm-чарт в репозитории фронтенда (`.helm`, `universal-chart`) и Kustomize-манифесты в инфраструктуре (`iac/apps/prescriptions`) описывают один и тот же сервис по-разному — стоит зафиксировать единый источник истины.
|
||
- **Несогласованные имена**: `SERVICE_NAME=prescriptions-frontend` (мн. ч.), а `deployment.name`/`image.name` в `.helm` — `prescription-frontend` (ед. ч.). В инфра-манифестах deployment называется просто `frontend`.
|
||
- **Версии Node расходятся**: разработка — `v20.16.0` (`.nvmrc`), сборка образа — `node:15` (`Dockerfile`).
|
||
- **Мёртвая конфигурация**: экспорт `hosts` в `networking.config.js` (внедрение `__<service>_host`) и `module/Env` (`IEnv`, `process.env as IEnv`) в коде модуля не используются; `dotenv-webpack` присутствует в devDependencies, но не подключён в `webpack.config.js`. `networking.config.js` реально используется только в `webpack.dev.js` (прокси dev-сервера).
|
||
|
||
## Минимальный набор для сборки
|
||
|
||
- `BUILD_ENV` — одно из `local`/`stage`/`preprod`/`prod`/`contour` (обязательно);
|
||
- `NPM_TOKEN` — для установки приватных пакетов `@sarex-team/*` из nexus;
|
||
- (опционально) `STORYBOOK=true` — при сборке/запуске Storybook;
|
||
- (для e2e) `SRX_LOGIN`, `SRX_PASSWORD` в `cypress.env.json`.
|