Astro 6 уже здесь! В Astro 6 появилось сразу несколько крупных возможностей: встроенный Fonts API, API для Content Security Policy и поддержка Live Content Collections, которые работают с внешним контентом через единый слой данных Astro.

Параллельно команда серьезно переработала dev-сервер Astro и значительную часть сборочного пайплайна. Благодаря новому Environment API из Vite Astro теперь может запускать тот же самый production-runtime прямо во время разработки. А значит, ситуаций в духе «локально работает, в проде ломается» станет заметно меньше — особенно на рантаймах не из мира Node.js, таких как Cloudflare Workers, Bun и Deno.

Вот ключевые изменения релиза:

  • переработанный astro dev;
  • улучшенная поддержка Cloudflare;
  • встроенный Fonts API;
  • Live Content Collections;
  • Content Security Policy;
  • обновление ключевых пакетов;
  • экспериментальный Rust-компилятор;
  • экспериментальный Queued Rendering;
  • экспериментальный Route Caching;
  • новости сообщества.

И ещё один важный момент: в Astro 6 появился экспериментальный новый компилятор на Rust — наследник исходного Go-компилятора для .astro. Пока это ранняя версия, но результаты уже впечатляют, а в некоторых сценариях новый компилятор даже надёжнее текущего Go-варианта. В ветке 6.x команда планирует и дальше развивать инструменты на Rust, чтобы улучшить производительность и масштабируемость крупных сайтов.

Обновиться можно уже сейчас

Чтобы обновить существующий проект до Astro 6, используйте автоматический CLI-инструмент @astrojs/upgrade:

# Рекомендуется:
npx @astrojs/upgrade
 
# Вручную:
npm install astro@latest

Для нового проекта достаточно выполнить:

npm create astro@latest

Переработанный astro dev

Изначально dev-сервер Astro проектировался под Node.js — и для большинства пользователей этого действительно хватало. Но по мере роста популярности Cloudflare Workers, Bun и Deno это ограничение стало всё заметнее. Разработчики, которые целились в эти платформы, не могли запускать свой реальный production-runtime во время разработки. В итоге локальное поведение и то, что уезжало в прод, могли различаться.

В Astro 6 это изменилось. За счёт нового Environment API из Vite команда смогла научить astro dev запускать кастомное runtime-окружение прямо в процессе разработки. Теперь dev-сервер и build-пайплайн проходят по одним и тем же кодовым путям, а опыт разработки стал гораздо ближе к реальному production.

Особенно болезненно это ощущалось у пользователей Cloudflare. Локально dev-сервер работал на Node.js, а в продакшене всё крутилось на рантайме workerd от Cloudflare. Ошибки всплывали только после деплоя. А биндинги Cloudflare — KV, D1, R2, Durable Objects — вообще были недоступны во время разработки. По сути, приходилось писать код вслепую и надеяться, что в проде всё заведётся.

Обновлённый адаптер @astrojs/cloudflare теперь запускает workerd на всех этапах: в разработке, при пререндеринге и в продакшене. Вы можете работать напрямую с платформенными API Cloudflare через cloudflare:workers и получать полный доступ к локальным биндингам. Больше не нужны ни симуляционные прослойки, ни обходные решения через Astro.locals.runtime. Эта работа выросла из официального партнёрства Astro с Cloudflare, о котором команда объявила в прошлом году, с целью сделать Cloudflare полноценной платформой первого класса для Astro.

Встроенный Fonts API

Почти каждый сайт использует кастомные шрифты, но настроить их правильно на практике сложнее, чем кажется. Тут и компромиссы по производительности, и вопросы приватности, и множество мелких решений, в которых легко ошибиться.

В Astro 6 появился встроенный Fonts API, который берёт все эти сложности на себя. Вы настраиваете шрифты из локальных файлов или из провайдеров вроде Google и Fontsource, а Astro сам делает всё остальное: скачивает и кэширует файлы для self-hosting, генерирует оптимизированные fallback-шрифты и добавляет preload-ссылки. В результате сайт остаётся быстрым, а данные пользователей — более защищёнными.

Для начала нужно описать объект fonts с одним или несколькими шрифтами, которые вы хотите использовать в проекте:

import { defineConfig, fontProviders } from 'astro/config';
 
export default defineConfig({
  fonts: [
    {
      name: 'Roboto',
      cssVariable: '--font-roboto',
      provider: fontProviders.fontsource(),
    },
  ],
});

Затем можно добавить компонент <Font /> и стили там, где это нужно: в глобальном layout, на отдельной странице или даже в конкретном фрагменте сайта.

---
import { Font } from 'astro:assets';
---
 
<Font cssVariable="--font-roboto" preload />
<style is:global>
  body {
    font-family: var(--font-roboto);
  }
</style>

За кулисами Astro скачает файлы шрифта, создаст оптимизированные fallback-варианты и добавит правильные preload-подсказки. То есть вы получаете best practice-загрузку шрифтов без ручной настройки всей этой механики.

Подробнее — в гайде по шрифтам.

Live Content Collections

В Astro 6 Live Content Collections вышли в стабильную стадию. Это приносит в единый слой данных Astro возможность получать контент в момент запроса.

Content Collections стали важной частью Astro ещё с версии 2.0. Но до сих пор для обновления контента почти всегда требовалась новая сборка. Live Content Collections работают иначе: они подтягивают контент прямо во время запроса, используя те же API, но уже без необходимости пересобирать сайт. Контент обновляется сразу после публикации, не затрагивая build-пайплайн. Это особенно удобно для CMS, API-данных и редакционных обновлений, которые должны появляться на сайте мгновенно.

Чтобы описать live-источник, используется defineLiveCollection() в src/live.config.ts:

import { defineLiveCollection } from 'astro:content';
import { z } from 'astro/zod';
import { cmsLoader } from './loaders/my-cms';
 
const updates = defineLiveCollection({
  loader: cmsLoader({ apiKey: process.env.MY_API_KEY }),
  schema: z.object({
    slug: z.string(),
    title: z.string(),
    excerpt: z.string(),
    publishedAt: z.coerce.date(),
  }),
});
 
export const collections = { updates };

После этого live-контент можно запрашивать на странице со встроенной обработкой ошибок:

---
import { getLiveEntry } from 'astro:content';
 
const { entry: update, error } = await getLiveEntry(
  'updates',
  Astro.params.slug,
);
 
if (error || !update) {
  return Astro.redirect('/404');
}
---
 
<h1>{update.data.title}</h1>
<p>{update.data.excerpt}</p>
<time>{update.data.publishedAt.toDateString()}</time>

Live Content Collections используют те же знакомые API, что и обычные build-time collections: getCollection(), getEntry(), схемы, загрузчики. Поэтому новую ментальную модель осваивать не придётся. Если вашему контенту нужна актуальность в реальном времени — создаёте live-коллекцию и live-loader, и контент обновляется на каждом запросе. Если нет — можно оставить обычные коллекции ради максимальной производительности. Оба подхода спокойно уживаются в одном проекте.

Подробности — в гайде по content collections.

Content Security Policy

API для настройки Content Security Policy в Astro 6 тоже стало стабильным. Astro — один из первых JavaScript-метафреймворков, который предлагает встроенную конфигурацию CSP и для статических, и для динамических страниц, причём как в server-, так и в serverless-окружении.

Поддержка CSP в подобном фреймворке — задача коварная. Нужно знать обо всех скриптах и стилях на странице, чтобы вычислить их хэши и включить их в политику. Для статических страниц это можно сделать на этапе сборки. Но для динамических страниц содержимое способно меняться от запроса к запросу — а значит, хэши приходится вычислять на лету и подставлять нужные заголовки во время выполнения. Поддержать оба режима в едином API довольно сложно, и именно поэтому другие метафреймворки до этого до сих пор толком не добрались.

Базовая настройка очень простая: достаточно включить CSP одним флагом, а Astro сам захэширует все скрипты и стили и сгенерирует нужные заголовки.

import { defineConfig } from 'astro/config';
 
export default defineConfig({
  security: { csp: true },
});

Для большинства сайтов этого уже достаточно. А если нужен более тонкий контроль — например, свои алгоритмы хэширования или дополнительные директивы для внешних скриптов и стилей, доступен полный API конфигурации:

import { defineConfig } from 'astro/config';
 
export default defineConfig({
  security: {
    csp: {
      algorithm: 'SHA-512',
      directives: [
        "default-src 'self'",
        "img-src 'self' https://images.cdn.example.com",
      ],
      styleDirective: { hashes: ['sha384-styleHash'] },
      scriptDirective: { hashes: ['sha384-scriptHash'] },
    },
  },
});

После стабилизации эта возможность также умеет работать с responsive images в Astro из коробки. Стили адаптивных изображений рассчитываются во время сборки и применяются через CSS-классы и data-*-атрибуты, поэтому их можно автоматически захэшировать и включить в CSP без дополнительной настройки.

Подробности — в справке по security-конфигурации.

Обновлённые пакеты

В Astro 6 также обновили несколько ключевых зависимостей:

  • Vite 7 теперь используется во всём Astro и во всех пакетах @astrojs. Если проект жёстко фиксирует свою версию Vite, перед обновлением до Astro 6 её нужно поднять до v7 или выше.
  • Shiki 4 теперь отвечает за подсветку кода в компоненте <Code /> и в code-блоках Markdown/MDX.
  • Zod 4 теперь используется для валидации content-схем. При описании схем Zod нужно импортировать из astro/zod, а не из astro:content.

Кроме того, Astro 6 теперь требует Node 22 или новее и прекращает поддержку Node 18 и Node 20, которые уже вышли из жизненного цикла или близки к этому. Node 22 быстрее, безопаснее и позволяет избавиться от полифиллов для старых версий Node. В результате пакет становится меньше, проще в поддержке, а сам Astro — производительнее.

Пошаговые детали миграции есть в гайде по обновлению.

Экспериментально: Rust Compiler

В Astro 6 появился экспериментальный новый компилятор на Rust — преемник оригинального Go-компилятора .astro.

По словам команды, всё началось как AI-эксперимент во время обновления Go-компилятора к Astro 6. Но довольно быстро вопрос «а это вообще сработает?» сменился на «почему это до сих пор не включено по умолчанию?». Новый компилятор быстрее, выдаёт более сильные диагностические сообщения и в некоторых случаях даже надёжнее текущего варианта на Go. В будущем команда надеется сделать его стандартным компилятором в одном из следующих крупных релизов.

Попробовать его можно уже сейчас: нужно включить флаг rustCompiler и установить пакет @astrojs/compiler-rs.

npm install @astrojs/compiler-rs
import { defineConfig } from 'astro/config';
 
export default defineConfig({
  experimental: {
    rustCompiler: true,
  },
});

Команда активно исследует и другие инструменты на Rust для экосистемы Astro и обещает рассказать о них позже.

Подробнее — в документации по Rust Compiler.

Экспериментально: Queued Rendering

В Astro 6 появилась экспериментальная стратегия рендеринга, которая, по ранним бенчмаркам, может дать до 2 раз более быстрый рендеринг.

Сейчас Astro рендерит компоненты рекурсивно: функции рендера вызывают сами себя, проходя по дереву компонентов. Queued Rendering заменяет это двухпроходным подходом: на первом проходе дерево обходится и формируется упорядоченная очередь, а на втором она уже рендерится. Это не только быстрее, но и экономнее по памяти. В Astro v7 команда планирует сделать этот подход основным.

Включить эксперимент можно так:

import { defineConfig } from 'astro/config';
 
export default defineConfig({
  experimental: {
    queuedRendering: {
      enabled: true,
    },
  },
});

Подробнее — в документации по queued rendering, где также описаны дополнительные опции вроде node pooling и content caching.

Экспериментально: Route Caching

Ещё одна экспериментальная возможность в Astro 6 — API для route caching. Оно даёт платформенно-независимый способ кэшировать server-rendered-ответы, используя стандартную веб-семантику кэширования.

Кэшировать SSR-ответы сегодня сложнее, чем должно быть. У каждого хостинга свои правила, и единого способа управлять этим из кода приложения нет. Route caching даёт единый API: вы задаёте кэш-директивы внутри маршрутов, а Astro уже сам разбирается, как применить их на конкретной платформе.

Для начала нужно указать cache provider в конфиге Astro. Он определяет, где будут храниться закэшированные ответы. В комплекте уже идёт встроенный провайдер memoryCache:

import { defineConfig } from 'astro/config';
import { memoryCache } from 'astro/config';
 
export default defineConfig({
  experimental: {
    cache: { provider: memoryCache() },
  },
});

Затем можно использовать Astro.cache (или context.cache в API-роутах), чтобы управлять кэшированием на уровне каждого запроса. Например, задавать время жизни кэша, окно stale-while-revalidate и теги для точечной инвалидции.

---
Astro.cache.set({
  maxAge: 120, // Кэшировать 2 минуты
  swr: 60, // Ещё 1 минуту можно отдавать устаревший ответ, пока идёт перевалидация
  tags: ['home'], // Тег для точечной инвалидции
});
---
 
<html><body>Cached page</body></html>

Именно здесь особенно хорошо проявляется единый content layer Astro. Route caching напрямую интегрируется с live content collections и автоматически отслеживает зависимости между страницами и контентными сущностями. Если меняется запись контента, все кэшированные ответы, которые от неё зависят, инвалидируются автоматически:

import { getEntry } from 'astro:content';
const product = await getEntry('products', Astro.params.slug);
 
// Когда product изменится, Astro автоматически инвалидирует эту закэшированную страницу:
Astro.cache.set(product);

Первая версия использует простой in-memory cache provider, который особенно хорошо подходит для Node.js-адаптера. Команда обещает в ближайшие недели добавить провайдеры кэша и для других платформ, которые поддерживает Astro. Также они рассчитывают, что сообщество создаст провайдеры для CDN-сервисов и внешних хранилищ вроде Redis.

Подробности — в документации по route caching.

Итог

Astro 6 — это не просто набор новых фич, а заметный шаг в сторону более зрелой и цельной платформы. С одной стороны, релиз приносит удобные прикладные инструменты вроде Fonts API, Live Content Collections и стабильного CSP. С другой — глубоко улучшает архитектуру разработки за счёт нового astro dev, который умеет запускать реальный production-runtime уже на этапе локальной работы.

Особенно интересно, что команда параллельно закладывает фундамент на будущее: новый компилятор на Rust, новая стратегия рендеринга и платформенно-независимое кэширование маршрутов выглядят как задел на следующие большие версии Astro.


Теги: astro, vite, webdev

Источник