Files
homepage/spec/migration.md

292 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# План миграции сайта vakhrushev.me с Sculpin на Astro
## Обзор текущего состояния
### Стек
- **Генератор**: Sculpin 3 (PHP 8)
- **Шаблоны**: Twig (base → internal → article, три уровня наследования)
- **Фронтенд**: Webpack 4, SCSS, Vue 2 (интерактивная демка гадалки)
- **Сборка**: Docker (PHP + Node контейнеры), Taskfile
- **Деплой**: Docker-образ nginx, Ansible на личный сервер
- **Аналитика**: Яндекс.Метрика
- **Шрифты**: Google Fonts (PT Serif, Source Code Pro), Font Awesome 5
- **Кастомные бандлы Sculpin**: HtmlPrettier, SiteMap, TwigExtension (hashed_asset)
### Контент
- 8 статей в markdown (2019-2020), русский язык
- 1 статья с интерактивным Vue-компонентом (гадалка Шеннона)
- Страницы: главная, список статей, 404
- Atom-лента (ручной шаблон)
- Sitemap (кастомный бандл + шаблон)
- robots.txt
### Структура стилей
- Переменные SCSS: шрифт PT Serif 20px, ширина 740px, цвета GitHub
- Базовые стили, стили главной, стили внутренних страниц, навигация
- BEM-подобная методология
---
## Целевое состояние
### Стек
- **Генератор**: Astro
- **Стилизация**: Tailwind CSS
- **Интерактивность**: Vue 3 (islands, для гадалки и будущих компонентов)
- **Сборка**: Docker (один Node-контейнер), Taskfile
- **Деплой**: Docker-образ nginx, Ansible (без изменений)
### Разделы сайта
1. **Главная** — краткое описание, ссылки
2. **Блог** — статьи и эссе по программированию
3. **Галерея** — фотографии (новый раздел, реализуется позже)
---
## Задачи
### Этап 1. Инициализация проекта Astro
#### 1.1. Создать проект Astro
- Инициализировать Astro в корне проекта (или в отдельной ветке)
- Настроить `astro.config.mjs`: site URL `https://vakhrushev.me`, язык `ru`
- Установить интеграции: `@astrojs/sitemap`, `@astrojs/rss`, `@astrojs/vue`, `@astrojs/tailwind`
- Настроить TypeScript (strict или relaxed — на усмотрение)
#### 1.2. Настроить Tailwind CSS
- Установить и настроить Tailwind
- Перенести дизайн-токены из SCSS-переменных в Tailwind-конфигурацию:
- Шрифты: PT Serif (serif), Source Code Pro (mono)
- Цвета: `#24292e` (текст), `#0366d6` (ссылки), `#e6e6e6` (линии)
- Ширина контента: 740px
- Размер шрифта: 20px базовый
#### 1.3. Настроить Docker для сборки
- Заменить два Docker-образа (PHP + Node) одним Node-образом
- Использовать актуальную LTS-версию Node (22)
- Удалить PHP Dockerfile — он больше не нужен
- Сохранить `Dockerfile.nginx.prod`, обновить путь: `dist/` вместо `output_prod/`
#### 1.4. Обновить Taskfile
- Убрать задачи: `composer`, `sculpin`, `shell-node`, `format-php`
- Обновить задачи сборки:
- `build-dev`: `astro build` (dev-режим — через `astro dev`)
- `build-prod`: `astro build`
- Обновить задачу `deploy`: путь к собранным файлам `dist/`
- Добавить задачу `dev`: запуск `astro dev` для локальной разработки
- Сохранить структуру Docker-команд через Taskfile
---
### Этап 2. Лейауты и компоненты
#### 2.1. Создать базовый лейаут `BaseLayout.astro`
Аналог текущего `base.html.twig`. Должен включать:
- `<html lang="ru">`, мета-теги (charset, viewport, description, keywords)
- Open Graph мета-теги (og:site_name, og:title, og:description, og:url, og:locale)
- Подключение шрифтов Google Fonts (PT Serif, Source Code Pro)
- Яндекс.Метрика (вынести в отдельный компонент `YandexMetrika.astro`)
- Yandex verification мета-тег
- Слот для контента
Параметры (props): `title`, `description`, `keywords`
#### 2.2. Создать лейаут для внутренних страниц `InternalLayout.astro`
Аналог `internal.html.twig`:
- Использует `BaseLayout`
- Навигация (компонент `Navigation.astro`)
- Контейнер `.page` с ограничением ширины
#### 2.3. Создать лейаут для статей `ArticleLayout.astro`
Аналог `article.html.twig`:
- Использует `InternalLayout`
- Заголовок статьи `<h1>`
- Дата публикации и email внизу
- Слот для содержимого статьи
#### 2.4. Создать общие компоненты
- `Navigation.astro` — навигация (Главная, Блог, Галерея)
- `YandexMetrika.astro` — код счетчика аналитики
- `ArticleList.astro` — список статей, сгруппированных по годам
Особенность: Font Awesome больше не нужен (социальные ссылки удалены в коммите `63a324c`).
Если понадобятся иконки — использовать `astro-icon` или inline SVG.
---
### Этап 3. Content Collections и перенос статей
#### 3.1. Настроить Content Collection для статей
- Создать `src/content/articles/` для markdown-файлов
- Определить схему в `src/content.config.ts`:
```ts
{
title: z.string(),
description: z.string().optional(),
date: z.date(), // извлечь из имени файла или добавить в frontmatter
keywords: z.array(z.string()).optional(),
tags: z.array(z.string()).optional(),
draft: z.boolean().default(false),
}
```
#### 3.2. Перенести статьи
Перенести 8 markdown-файлов из `source/_articles/` в `src/content/articles/`.
Необходимые изменения в каждом файле:
- Удалить Sculpin-специфичные поля frontmatter (`layout`, `styles`, `scripts`, `use`)
- Добавить поле `date` (сейчас дата в имени файла, нужно продублировать в frontmatter)
- Оставить `title`, `description`, `keywords`
- Опционально: добавить `tags` для будущей фильтрации
Список статей:
1. `2019-05-01-predictor.md` — **ОСОБЫЙ СЛУЧАЙ**, см. задачу 3.3
2. `2019-06-01-php-serialization.md`
3. `2019-06-28-storytelling.md`
4. `2019-08-08-yandex-disk-image-hosting.md`
5. `2019-09-26-highload-videos.md`
6. `2020-06-27-interesting-programming-blogs.md`
7. `2020-06-27-type-discriminant.md`
8. `2020-11-08-nullable-fields.md`
#### 3.3. Перенести статью с интерактивным компонентом (гадалка)
Статья `predictor.md` содержит встроенный Vue-компонент `<div id="app"></div>`.
Шаги:
- Переименовать файл в `.mdx`
- Обновить Vue-компонент `PredictorDemo.vue` до Vue 3 (Composition API или Options API)
- `@anwinged/predictor` — проверить совместимость с Vue 3, при необходимости обновить
- Перенести scoped-стили компонента на Tailwind или оставить scoped CSS
- В MDX-файле: импортировать компонент и использовать `<PredictorDemo client:visible />`
- Удалить ручное подключение JS/CSS через frontmatter (`styles`, `scripts`)
---
### Этап 4. Страницы
#### 4.1. Главная страница `src/pages/index.astro`
- Использовать `BaseLayout`
- Имя, краткое описание (обновить текст — актуализировать информацию о себе)
- Ссылки: email, git, другие
- Список последних статей (через `getCollection('articles')`)
#### 4.2. Страница списка статей `src/pages/articles/index.astro`
- Использовать `InternalLayout`
- Список всех статей, сгруппированных по годам (как сейчас в `article_list.twig`)
- Сортировка по дате, от новых к старым
#### 4.3. Динамические страницы статей `src/pages/articles/[...slug].astro`
- Использовать `ArticleLayout`
- Рендеринг markdown/MDX содержимого через `render()`
- SEO мета-теги из frontmatter
#### 4.4. Страница 404 `src/pages/404.astro`
- Использовать `InternalLayout`
- Текст "Страница не найдена" и ссылка на главную
#### 4.5. Страница галереи `src/pages/gallery/index.astro` (заглушка)
- Использовать `InternalLayout`
- Placeholder-страница "Скоро здесь будут фотографии"
- Полноценная реализация — отдельная задача в будущем
---
### Этап 5. RSS, Sitemap, SEO
#### 5.1. Настроить RSS-ленту
- Создать `src/pages/rss.xml.ts` с использованием `@astrojs/rss`
- Включить все статьи (title, description, date, link)
- URL: `/rss.xml`
- Для обратной совместимости: добавить редирект `/atom.xml` → `/rss.xml` (в nginx или через Astro)
#### 5.2. Настроить Sitemap
- Интеграция `@astrojs/sitemap` уже генерирует sitemap автоматически
- Убедиться, что 404 и служебные страницы исключены
#### 5.3. Настроить robots.txt
- Создать `public/robots.txt` со ссылкой на sitemap
#### 5.4. Open Graph и мета-теги
- Уже реализовано в BaseLayout (задача 2.1)
- Проверить корректность на каждом типе страниц
---
### Этап 6. Сборка и деплой
#### 6.1. Обновить Docker-сборку
- Новый `docker/node/Dockerfile` на Node 22 LTS
- PHP Dockerfile удалить
- Обновить `Dockerfile.nginx.prod`:
```dockerfile
FROM nginx:stable
COPY dist /usr/share/nginx/html
```
- Добавить конфиг nginx для SPA fallback (404.html) и кэширования статики
#### 6.2. Обновить Taskfile
Финальная версия задач:
```yaml
tasks:
dev: # astro dev (локальная разработка)
build-prod: # astro build
deploy: # build-prod → docker build → ansible
```
#### 6.3. Проверить деплой
- Собрать Docker-образ
- Проверить, что все страницы отдаются корректно
- Проверить 404
- Проверить RSS и sitemap
---
### Этап 7. Очистка
#### 7.1. Удалить файлы Sculpin
- `app/` — SculpinKernel, конфиги
- `bundle/` — кастомные бандлы (HtmlPrettier, SiteMap, TwigExtension)
- `source/` — старые шаблоны, ассеты, контент (после проверки, что всё перенесено)
- `composer.json`, `composer.lock`
- `docker/php/Dockerfile`
- `webpack.config.js`
- `.php-cs-fixer.php`
#### 7.2. Обновить package.json
- Удалить старые зависимости (webpack, babel, vue 2, node-sass, и т.д.)
- Удалить старые npm-скрипты
- Оставить только Astro и его зависимости
#### 7.3. Обновить .gitignore
- Убрать `output_dev/`, `output_prod/`, `vendor/`
- Добавить `dist/`, `.astro/`, `node_modules/`
#### 7.4. Обновить README.md
- Описание нового стека
- Инструкции по локальной разработке и деплою
---
## Сохранение URL-совместимости
Текущие URL статей имеют формат: `/articles/YYYY/MM/DD/slug/`
(например, `/articles/2019/05/01/predictor/`).
Нужно сохранить эти URL, чтобы не сломать внешние ссылки. Варианты:
1. **Настроить slug в Astro** — использовать `getStaticPaths()` с кастомными slug, повторяющими текущую структуру
2. **Редиректы в nginx** — если хочется упростить URL-структуру (например, `/articles/predictor/`), настроить 301-редиректы со старых URL
Рекомендация: упростить URL до `/articles/slug/` и настроить редиректы в nginx для старых URL.
---
## Порядок выполнения
```
Этап 1 (инициализация) → Этап 2 (лейауты) → Этап 3 (контент)
→ Этап 4 (страницы) → Этап 5 (RSS/sitemap) → Этап 6 (деплой) → Этап 7 (очистка)
```
Этапы 2 и 3 можно частично выполнять параллельно.
Этап 7 выполняется только после полной проверки нового сайта.