90 lines
4.5 KiB
Markdown
90 lines
4.5 KiB
Markdown
# Frontend JS Architecture
|
||
|
||
## Цель
|
||
|
||
- Держать `public/js/main.js` минимальным entrypoint.
|
||
- Делить код по фичам, а не по страницам.
|
||
- Снижать связность и дублирование.
|
||
|
||
## Структура
|
||
|
||
- `public/js/main.js` — только импорты и вызовы `init*`.
|
||
- `public/js/modules/theme/*` — тема и панель стилей.
|
||
- `public/js/modules/header/*` — шапка, скролл, overflow-навигация.
|
||
- `public/js/modules/experience/*` — masonry, expand, hover-эффекты.
|
||
- `public/js/modules/mini-projects/*` — masonry и раскрытие секции мини-проектов.
|
||
- `public/js/modules/cases/*` — медиалогика кейсов.
|
||
- `public/js/modules/ui/*` — локальные UI-фичи (копирование, cookie, hero и т.д.).
|
||
- `public/js/modules/shared/*` — переиспользуемые утилиты.
|
||
|
||
## Правила зависимостей
|
||
|
||
- Разрешено: `feature -> shared`.
|
||
- Нежелательно: `feature -> feature`.
|
||
- Запрещено: циклические зависимости.
|
||
- Если логика нужна в 2+ фичах, переносить ее в `shared`.
|
||
|
||
## Соглашения по именованию
|
||
|
||
- Инициализаторы: `initFeatureName`.
|
||
- Файлы с разделением ответственности:
|
||
- `*-core.js` — состояние, вычисления, чистая логика.
|
||
- `*-controls.js` — DOM и события.
|
||
- Утилиты: короткие имена по области (`math.js`, `media.js`, `dom.js`).
|
||
|
||
## Контракт для init-функций
|
||
|
||
- Функция должна быть безопасной на любой странице.
|
||
- Если нужного DOM нет, делать ранний `return`.
|
||
- Не бросать исключения при отсутствии опциональных API браузера.
|
||
- По возможности избегать глобального состояния.
|
||
|
||
## Как добавить новую фичу
|
||
|
||
1. Создать модуль в нужной feature-папке, например `public/js/modules/ui/new-feature.js`.
|
||
2. Экспортировать `initNewFeature`.
|
||
3. В `public/js/main.js`:
|
||
- добавить `import { initNewFeature } ...`;
|
||
- вызвать `initNewFeature()` в блоке инициализации.
|
||
4. Если часть кода переиспользуется, вынести в `public/js/modules/shared/*`.
|
||
|
||
## Минимальный шаблон фичи
|
||
|
||
```js
|
||
export function initNewFeature() {
|
||
const root = document.querySelector("[data-new-feature]");
|
||
if (!root) return;
|
||
|
||
// logic
|
||
}
|
||
```
|
||
|
||
## Чеклист перед PR
|
||
|
||
- Проверить базовый smoke на страницах с этой фичей.
|
||
- Проверить `prefers-reduced-motion`, если есть анимации.
|
||
- Проверить resize/scroll сценарии, если есть геометрические вычисления.
|
||
- Проверить доступность: `aria-*`, keyboard-only навигация, Escape/Focus.
|
||
|
||
## Source/Build/Public для HTML
|
||
|
||
- `src/partials/*.html` — source of truth для общих блоков (header, fab, projects, contact, footer, cookie и т.д.).
|
||
- `src/pages/**/*.html` — source of truth для страниц с include-маркерами `{{> partial-name }}`.
|
||
- `public/assets/**` — картинки, видео, иконки сайта (редактируются вручную; сборка страниц их не копирует).
|
||
- `public/**/*.html` — только build-артефакт; руками не редактируем.
|
||
|
||
Эталон HTML-блоков для лонгрида кейса и порядок partials: **`docs/case-page-blocks.md`** (исходник-пример: `src/pages/cases/template-elements-demo.html`).
|
||
|
||
### Сборка страниц
|
||
|
||
- Команда: `npm run build:pages`.
|
||
- Скрипт: `scripts/build-pages.mjs`.
|
||
- Скрипт подставляет partials и переменные пути:
|
||
- `{{assetPrefix}}` (`""` для корня, `../` для `cases/*`),
|
||
- `{{casesPrefix}}` (`cases/` для корня, `""` для `cases/*`).
|
||
|
||
### Правило перед выкладкой
|
||
|
||
- Перед публикацией на хостинг всегда запускать `npm run build:pages` (или `npm run build`).
|
||
|