Вышел Astro 4.14! В релизе — первый экспериментальный Content Layer API, гибкое решение для управления контентом в Astro-проектах, поддержка Intellisense в файлах контента и многое другое.
Основные новинки:
- Экспериментально: Content Layer API
- Экспериментально: Intellisense в файлах контента
- Устарела поддержка динамических значений
prerender - Новый integration API
injectTypes - Поддержка metastrings в компоненте Code
Чтобы обновить существующий проект, используйте CLI @astrojs/upgrade. Или обновите вручную:
# Рекомендуется:npx @astrojs/upgrade
# Вручную:npm install astro@latestpnpm upgrade astro --latestyarn upgrade astro --latestExperimental: Content Layer API
В Astro 2.0 мы представили Content Collections — мощный способ управлять локальным контентом. Сотни тысяч разработчиков строят контентные сайты, но вы просили больше гибкости. Мы рады анонсировать экспериментальный Content Layer API — следующее поколение content collections.
Content Layer API расширяет collections за пределы локальных файлов в src/content/ — можно загружать контент откуда угодно, включая удалённые API. Новые collections работают рядом с существующими, миграция в своём темпе. Преимуществ много, но спешить не нужно — старые collections продолжат работать.
Performance
Content Layer API — первый шаг к быстрым сборкам сайтов с десятками или сотнями тысяч страниц. API эффективнее загружает контент, кэширует локально (без постоянных запросов к API) и значительно улучшил обработку локальных Markdown и MDX. Бенчмарк сборки сайта с 10 000 страниц на Macbook Air M1:
| Astro 4.13 | Astro 4.14 (Content Layer) | |||
|---|---|---|---|---|
| Markdown | Build Time | 136.29s | 25.96s | 5.3x faster |
| Memory | 763.50MB | 276.22MB | 64% less | |
| MDX | Build Time | 129.82s | 66.70s | 1.9x faster |
| Memory | 897.91MB | 674.39MB | 25% less |
Планируем дальше улучшать производительность, включая SQLite backend для ещё более крупных сайтов.
Getting started
Включите Content Layer API в конфиге Astro:
import { defineConfig } from 'astro/config';
export default defineConfig({ experimental: { contentLayer: true }})Затем создавайте collections в src/content/config.ts через Content Layer API.
Loading your content
Ядро API — loader: функция, загружающая контент из источника и кэширующая в локальное хранилище. Astro 4.14 поставляется с glob() и file() для локальных Markdown, MDX, Markdoc и JSON:
import { defineCollection, z } from 'astro:content';import { glob } from 'astro/loaders';
const blog = defineCollection({ // The ID is a slug generated from the path of the file relative to `base` loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }), schema: z.object({ title: z.string(), description: z.string(), publishDate: z.coerce.date(), })});
export const collections = { blog };Использование контента на сайте:
---import { getEntry, render } from 'astro:content';
const post = await getEntry('blog', Astro.params.slug);
const { Content } = await render(entry);---
<Content />Creating a loader
Вы не ограничены встроенными loaders — создавайте свои. Загружайте контент откуда угодно и возвращайте массив записей:
const countries = defineCollection({ loader: async () => { const response = await fetch("https://restcountries.com/v3.1/all"); const data = await response.json(); // Must return an array of entries with an id property, // or an object with IDs as keys and entries as values return data.map((country) => ({ id: country.cca3, ...country, })); }, // optionally add a schema to validate the data and make it type-safe for users // schema: z.object...});
export const collections = { countries };Для сложной логики — object loader: инкрементальные обновления, условная загрузка, полный доступ к хранилищу, динамическая схема. Подробнее: Content Layer API RFC.
Sharing your loaders
Loaders лучше, когда ими делятся! Создайте модуль, опубликуйте на npm — и любой сможет использовать. Тег astro-loader для поиска. Примеры loaders. Загрузка через RSS/Atom feed loader:
import { defineCollection } from "astro:content";import { feedLoader } from "@ascorbic/feed-loader";
const podcasts = defineCollection({ loader: feedLoader({ url: "https://feeds.99percentinvisible.org/99percentinvisible", }),});
export const collections = { podcasts };Learn more
Подробнее: Content Layer RFC и обратная связь.
Experimental: Intellisense inside content files
Astro 4.14 добавляет экспериментальный Intellisense во frontmatter контента. Автодополнение, валидация, hover и другое для ключей и значений frontmatter — на основе content schemas прямо в редакторе.
Доступно в VS Code и редакторах с Language Server Protocol для Markdown, MDX и Markdoc.
Для включения добавьте в конфиг Astro:
import { defineConfig } from 'astro';
export default defineConfig({ experimental: { contentIntellisense: true }})В VS Code включите настройку astro.content-intellisense. В других редакторах передайте contentIntellisense: true в параметры инициализации Astro language server.
{ "astro.content-intellisense": true}Пока работает только в редакторе; в astro check появится в будущем.
Deprecate support for dynamic prerender values
Для улучшения bundling и tree-shaking Astro 4.14 устаревает динамические значения опции prerender на страницах Astro.
Замена — новый хук astro:route:setup в интеграциях для динамического управления prerendering:
--- export const prerender = import.meta.env.PROD;---import { defineConfig } from 'astro/config';
export default defineConfig({ integrations: [setPrerender()],});
function setPrerender() { return { name: 'set-prerender', hooks: { 'astro:route:setup': ({ route }) => { if (route.component.endsWith('/blog/[slug].astro')) { route.prerender = true; } }, }, };}New injectTypes integration API
Генерация типов набирает обороты — и Astro не исключение! Мы активно используем её для Astro DB, Content Collections и Content Layer API.
Благодаря @florian-lefebvre интеграции могут внедрять типы через новый API injectTypes:
export default { name: 'my-integration', 'astro:config:done': ({ injectTypes }) => { injectTypes({ filename: "types.d.ts", content: "declare module 'virtual:my-integration' {}" }) }};Подробнее: документация Astro integration API.
Support for metastrings in the Code component
Astro 4.14 добавляет атрибут meta в компонент Code. Он имитирует свойства code blocks в Markdown, например ```js astro=cool, для Shiki transformers:
---import { Code } from "astro:components";import { transformerMetaHighlight } from '@shikijs/transformers';---<Code code={code} lang="js" transformers={[transformerMetaHighlight()]} meta="{1,3}" />Спасибо @jcayzac!
Bug Fixes and Special Thanks
Как обычно, Astro 4.14 включает исправления и улучшения, не вошедшие в этот пост! Полные release notes.
Спасибо Sarah Rainsberger (@sarah11918), Yan (@yanthomasdev), Bjorn Lu (@bluwy) и всем остальным контрибьюторам релиза.
