Astro 4.14

Автор
Erika
Matt Kane

Вышел Astro 4.14! В релизе — первый экспериментальный Content Layer API, гибкое решение для управления контентом в Astro-проектах, поддержка Intellisense в файлах контента и многое другое.

Основные новинки:

Чтобы обновить существующий проект, используйте CLI @astrojs/upgrade. Или обновите вручную:

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

Experimental: 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:

src/content/config.ts
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 — создавайте свои. Загружайте контент откуда угодно и возвращайте массив записей:

src/content/config.ts
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:

src/content/config.ts
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;
---
astro.config.mjs
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:

my-integration/index.js
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) и всем остальным контрибьюторам релиза.