Astro 2.5

Astro 2.5
Оглавление
  1. # src/content/blog/welcome.md

Мы только что выпустили Astro 2.5 с большим списком функций, включая:

Коллекции данных и ссылки

Коллекции данных — это первоклассное решение Astro для управления и создания контента. В Astro 2.5 эта история получила еще большее развитие благодаря новым форматам данных и ссылкам на коллекции.

Во-первых, мы ввели новый тип: свойство ‘data’ для хранения форматов данных, таких как JSON и YAML, в собственных коллекциях. Это открывает возможности использования коллекций для новых форм контента, включая профили авторов, многократно используемый альт текст изображений, словари переводов и многое другое.

Создавайте коллекции данных вместе с существующими коллекциями контента:

src/content/
    blog/
        week-1.md
        week-2.md
+    authors/
+        grace-hopper.json
+        alan-turing.json

Настройте их с помощью нового свойства type: ‘data’:

// src/content/config.ts
import { defineCollection, z } from "astro:content"

const authors = defineCollection({
	type: "data",
	schema: z.object({
		name: z.string(),
		socialLink: z.string().url(),
	}),
})

const blog = defineCollection({
	type: "content",
	schema: z.object({
		/* ... */
	}),
})

export const collections = { blog: blog, authors: authors }

Вы также можете захотеть ”ссылаться” на связанные записи. Обычный пример - запись в блоге, которая ссылается на многократно используемые профили авторов, хранящиеся в виде JSON в коллекции данных, или URL-адреса связанных записей, хранящиеся в той же коллекции. Вы можете настроить эти отношения с помощью новой функции reference():

import { defineCollection, reference, z } from "astro:content"

const blog = defineCollection({
	type: "content",
	schema: z.object({
		title: z.string(),
		// Reference a single author from the `authors` collection by `id`
		author: reference("authors"),
		// Reference an array of related posts from the `blog` collection by `slug`
		relatedPosts: z.array(reference("blog")),
	}),
})

const authors = defineCollection({
	type: "data",
	schema: z.object({
		/** ... */
	}),
})

export const collections = { blog, authors }

Теперь каждая запись блога может ссылаться на связанные записи с безопасной для типов валидацией:

# src/content/blog/welcome.md

title: “Welcome to my blog” author: ben-holmes # references src/content/authors/ben-holmes.json relatedPosts:

  • about-me # references src/content/blog/about-me.md
  • my-year-in-review # references src/content/blog/my-year-in-review.md ---

Подробные примеры смотрите в обновленном руководстве по коллекциям контента.

Статический гибридный рендеринг по умолчанию (экспериментальный)

В версии 2.0 мы добавили возможность предварительного рендеринга отдельных страниц в приложениях SSR. Теперь в версии 2.5 вы можете сделать и обратное; в основном статическом сайте вы можете указать некоторые маршруты, которые не будут подвергаться предварительному рендерингу.

Эта новая ”гибридная” опция вывода на сервер перевернет стандартное поведение пререндеринга в SSR так, что вам больше не придется отмечать каждый статический маршрут, который вы хотите пререндерить. Эта опция будет помечена как экспериментальная в течение короткого периода времени, пока мы стабилизируем крайние случаи. Вы можете использовать ее уже сегодня, включив флаг hybridOutput в экспериментальной секции вашего конфига и добавив адаптер:

astro.config.mjs

import { defineConfig } from "astro/config"
import nodejs from "@astrojs/node"

export default defineConfig({
	output: "hybrid",
	adapter: nodejs(),
	experimental: {
		hybridOutput: true,
	},
})

Как только вы это сделаете, весь ваш сайт будет предварительно отрисован по умолчанию. Вы можете отказаться от предварительного рендеринга, установив значение false для экспорта предварительного рендеринга любой страницы или конечной точки:

src/pages/contact.astro

--- 

export const prerender = false

if (Astro.request.method === "POST") {
	// handle form submission
}
--- 


<form method="POST">
	<input type="text" name="name" />
	<input type="email" name="email" />
	<button type="submit">Submit</button>
</form>

Пользовательские клиентские директивы (экспериментально)

Пользовательские клиентские директивы позволяют авторам интеграций определять новые директивы client: для получения большего контроля над загрузкой компонентов.

Интеграции могут добавлять их через новый API addClientDirective() хука astro:config:setup. Чтобы использовать этот API, включите customClientDirectives в экспериментальном разделе вашего конфига.

astro.config.mjs

import { defineConfig } from "astro/config"
import onClickDirective from "astro-click-directive"

export default defineConfig({
	integrations: [onClickDirective()],
	experimental: {
		customClientDirectives: true,
	},
})

astro-click-directive

export default function onClickDirective() {
	return {
		hooks: {
			"astro:config:setup": ({ addClientDirective }) => {
				addClientDirective({
					name: "click",
					entrypoint: "astro-click-directive/click.js",
				})
			},
		},
	}
}

Теперь вы можете использовать client:click для любых компонентов вашего фреймворка с полной поддержкой типов.

<Counter client:click />

См. документацию по клиентским директивам, чтобы узнать, как создавать такие типы интеграций.

Минификация HTML

Теперь вы можете отказаться от минификации HTML, создаваемого вашими компонентами Astro.

Используя опцию compressHTML, Astro удалит все пробельные символы из вашего HTML, включая переносы строк.

Мы хотели включить минификацию без ущерба для производительности. Для приложений с серверным рендерингом минификация при каждом рендеринге может оказаться дорогостоящей. С compressHTML ваши компоненты сжимаются только один раз компилятором Astro, а затем во время сборки.

Вы можете включить эту функцию в конфигурации:

import { defineConfig } from "astro/config"
export default defineConfig({
	compressHTML: true,
})

Примечание: сжатие происходит как в режиме разработки, так и в финальной сборке.

Хотя эта опция не сжимает HTML, создаваемый компонентом фреймворка, вы можете написать промежуточное ПО для сжатия HTML-ответов.

Параллельный рендеринг

Теперь Astro будет рендерить компоненты параллельно, так что компоненты, загружающие данные выше в дереве, больше не будут блокировать другие компоненты, которые также загружают данные, как в примере ниже:

<Delayed ms={30} />
<Delayed ms={20} />
<Delayed ms={40} />
<Delayed ms={10} />

Этот <Delayed /> компонент ждет определенное количество миллисекунд. Раньше каждый компонент должен был дождаться завершения предыдущего, прежде чем начать рендеринг. Теперь в версии 2.5 все они будут отрисовываться одновременно.

Забавный факт: мы пытались добавить эту оптимизацию в прошлом, но нам не хватало хороших бенчмарков, чтобы убедиться, что это не замедляет рендеринг. Недавние улучшения в нашей инфраструктуре бенчмарков CI позволили нам реализовать эту оптимизацию с уверенностью.

Помощник полиморфного типа

Astro теперь включает помощник TypeScript (Polymorphic) для упрощения создания компонентов, которые могут отображаться как различные элементы HTML с полной безопасностью типов. Это полезно для таких компонентов, как <Link>, которые могут отображаться как <a> или <button> в зависимости от переданных им реквизитов.

В приведенном ниже примере реализован полностью типизированный, полиморфный компонент, который может отображаться как любой элемент HTML. Тип HTMLTag используется для обеспечения того, что реквизит as является допустимым элементом HTML.

--- 

import { HTMLTag, Polymorphic } from "astro/types"

type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>

const { as: Tag, ...props } = Astro.props
--- 


<Tag {...props} />

Подробнее

В этот выпуск включены дополнительные исправления ошибок и улучшения. Ознакомьтесь с примечаниями к выпуску, чтобы узнать больше.