Деплой на AWS S3 и CloudFront

Развёртывание фронтенд-приложения, собранного с использованием Vite, в инфраструктуре AWS обычно опирается на связку S3 + CloudFront, где S3 используется как статическое хранилище артефактов сборки, а CloudFront выполняет роль CDN с кэшированием, TLS и глобальной доставкой контента.

Ключевая особенность Vite — генерация полностью статических файлов после команды сборки, что делает его идеально совместимым с объектным хранилищем.

Структура итоговой сборки Vite

После выполнения команды:

npm run build

Vite формирует директорию dist/, содержащую:

  • index.html — точка входа приложения
  • статические JS-бандлы (assets/*.js)
  • CSS-файлы
  • ассеты (изображения, шрифты и т.д.)
  • хешированные имена файлов для кэширования

Важный аспект: все зависимости оптимизированы и разбиты на чанки, что позволяет эффективно использовать CDN-кэширование.


Подготовка Vite-проекта к деплою

Настройка base path

При размещении приложения не в корне домена необходимо задать параметр base в конфигурации Vite:

// vite.config.js
export default {
  base: '/',
}

Для размещения в поддиректории:

export default {
  base: '/app/',
}

Этот параметр влияет на генерацию ссылок на ассеты в index.html и внутри бандлов.


Сборка production-версии

npm run build

Результат:

dist/
 ├── index.html
 ├── assets/
 │    ├── index-[hash].js
 │    ├── vendor-[hash].js
 │    └── index-[hash].css

Директория dist является единственным артефактом деплоя.


Развёртывание в Amazon S3

Создание S3 bucket

В AWS S3 создаётся bucket с уникальным именем, например:

  • my-vite-app-prod

Настройки bucket:

  • отключён public access block (для публичного сайта или используется CloudFront Origin Access Control)
  • включён static website hosting (опционально, если CloudFront не используется напрямую)

Загрузка файлов

Загрузка содержимого dist/:

aws s3 sync dist/ s3://my-vite-app-prod --delete

Параметр --delete синхронизирует bucket с локальной сборкой, удаляя устаревшие файлы.


Важные нюансы S3 для SPA

При использовании SPA (React/Vue/Svelte на Vite) необходимо учитывать маршрутизацию:

  • переход по /dashboard или /profile должен возвращать index.html
  • S3 по умолчанию возвращает 404 для несуществующих объектов

Решения:

1. Fallback через CloudFront (рекомендуется)

2. S3 Website configuration

Настройка:

  • Index document: index.html
  • Error document: index.html

Это позволяет SPA-роутеру корректно обрабатывать маршруты.


Интеграция CloudFront

Причины использования CloudFront

CloudFront добавляет:

  • глобальный CDN
  • TLS (HTTPS)
  • кеширование статики
  • компрессию (gzip/brotli)
  • контроль над заголовками
  • защиту origin (S3)

Создание distribution

Основные настройки:

  • Origin: S3 bucket
  • Origin access: OAC (Origin Access Control) или legacy OAI
  • Default root object: index.html

Настройка SPA routing через CloudFront

Для корректной работы SPA необходимо обработать 404 и редирект на index.html.

Используется Custom error responses:

  • HTTP Error Code: 403 и 404
  • Response Page Path: /index.html
  • HTTP Response Code: 200

Это гарантирует корректную работу маршрутов Vite-приложения.


Кэширование и стратегии обновления

Хешированные файлы

Vite автоматически добавляет hash в имена файлов:

app.8d31c1.js
vendor.3f9a21.js

Это позволяет:

  • устанавливать долгий cache-control
  • избегать проблем с обновлением

Настройка Cache-Control

Для CloudFront рекомендуется:

Для index.html

Cache-Control: no-cache

Для assets/*

Cache-Control: public, max-age=31536000, immutable

Такое разделение обеспечивает:

  • мгновенное обновление HTML
  • агрессивное кэширование ассетов

Инвалидация кеша CloudFront

После деплоя необходимо обновить CDN-кэш:

aws cloudfront create-invalidation \
  --distribution-id ABCD1234 \
  --paths "/*"

Более оптимально:

--paths "/index.html"

Поскольку хешированные файлы не требуют инвалидции.


Переменные окружения Vite в AWS деплое

Vite использует префикс VITE_:

VITE_API_URL=https://api.example.com

Доступ в коде:

import.meta.env.VITE_API_URL

Особенность:

  • переменные внедряются на этапе build
  • изменение требует пересборки

CI/CD для деплоя на S3 и CloudFront

Типовой pipeline включает:

Шаги сборки

npm ci
npm run build

Синхронизация с S3

aws s3 sync dist/ s3://my-vite-app-prod --delete

Инвалидация CloudFront

aws cloudfront create-invalidation \
  --distribution-id $DISTRIBUTION_ID \
  --paths "/index.html"

Пример GitHub Actions

name: Deploy Vite to S3

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - run: npm ci
      - run: npm run build

      - run: aws s3 sync dist/ s3://my-vite-app-prod --delete
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: us-east-1

      - run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.CLOUDFRONT_ID }} \
            --paths "/index.html"

Оптимизация производительности

Brotli и gzip

CloudFront поддерживает автоматическую компрессию, однако важно:

  • включить “Compress objects automatically”
  • убедиться, что origin не переопределяет encoding

Prefetch и preload

Vite может генерировать:

  • modulepreload для чанков
  • оптимизированные dynamic imports

CloudFront эффективно распределяет такие запросы благодаря HTTP/2 и HTTP/3.


HTTP/2 multiplexing

CDN позволяет:

  • параллельно загружать чанки
  • снижать latency
  • минимизировать блокировки очередей

Типичные проблемы и их причины

Белый экран после деплоя

Причины:

  • неверный base
  • неправильные пути ассетов
  • отсутствие rewrite на index.html

404 при обновлении страницы

Причина:

  • отсутствие SPA fallback в CloudFront или S3

Старые файлы после обновления

Причина:

  • кеш CloudFront
  • отсутствие инвалидции
  • неправильные cache-control заголовки

Ошибки CORS при API

Причина:

  • backend не настроен на домен CloudFront
  • отсутствуют заголовки:
Access-Control-Allow-Origin

Безопасность и доступ

Origin Access Control

Рекомендуемая схема:

  • S3 bucket полностью приватный
  • CloudFront имеет единственный доступ к origin

Это исключает прямой доступ к файлам S3.


HTTPS

CloudFront использует:

  • ACM certificate
  • обязательный redirect HTTP → HTTPS

Ограничение доступа

Дополнительно возможно:

  • signed URLs
  • signed cookies
  • geo restriction

Масштабирование архитектуры

При росте проекта добавляются:

  • несколько окружений (dev/stage/prod)
  • отдельные bucket’ы
  • отдельные CloudFront distributions
  • versioned deployments

Структура:

s3://app-prod
s3://app-stage
s3://app-dev

или через один bucket с префиксами:

/prod/
/stage/
/dev/

Работа с несколькими окружениями Vite

Конфигурация:

vite build --mode production
vite build --mode staging

Файлы:

.env.production
.env.staging

Использование S3 + CloudFront как production стандарта

Связка обеспечивает:

  • предсказуемый статический хостинг
  • минимальные задержки благодаря CDN
  • дешёвое масштабирование
  • совместимость с любым Vite SPA/MPA проектом
  • интеграцию с CI/CD системами