BLOG

記事一覧 タグ一覧

Astro v4 to v5

投稿日:

この記事は OUCC Advent Calendar 2024 の 8 日目の記事です。昨日の記事はまだ投稿されていません 🤔 本日は、Astro v4 から v5 までに追加された個人的に注目している機能を紹介します。

この記事には以下の内容は含まれません

  • 破壊的変更の説明
  • 詳細な説明
  • 完全な理解

主要な新機能

まず、Astroブログでも取り上げられてる主要な新機能について説明します。

Content Layer

Astro v5 では Content collections が大幅に変更されて Content Layer が追加されました。ローダー関数を使用してどこからでもデータが取得できます。 従来のtypeプロパティを使用した Content の指定方法は廃止され、ローカルファイルを読み込む組み込みのローダー関数が提供されるようになりました。

// src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
import { notionLoader } from "notion-astro-loader";

const blog = defineCollection({
  // Load data from Markdown files on disk
  loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
  schema: z.object({ /* optionally define a schema for type-safe data */  }),
});

const database = defineCollection({
  // Automatically fetch content in one line with a loader
  loader: notionLoader({ /* ... */ })
});

export const collections = { blog, database };

このローダーはStoryblok や Cloudinary などの外部サービスからデータを取得するためのものも提供されており、簡単に外部のCMSと連携できます。

Content Loaderについてのさらなる情報は公式サイトを参照してください。

従来の Content collections は Legacy flag をつけると引き続き使用できます。ただし、完全な互換性は保証されません。(例えばlayoutフィールドはサポートされていません)

import { defineConfig } from 'astro/config';
export default defineConfig({
  legacy: {
    collections: true
  }
});

Sever Islands

Astro v5 では、アイランドアーキテクチャがサーバーサイドまで拡張されました。これにより高性能な静的HTMLと動的なサーバー生成コンポーネントを組み合わせる事ができます。

以下のようにserver:deferを付与すると、まずフォールバックコンテンツが表示され、サーバーサイドでコンポーネントが生成されると差し替えられます。

レイアウトシフトの抑制にも役立ちそうです。

---
import Avatar from '../components/Avatar.astro';
import GenericAvatar from '../components/GenericAvatar.astro';
---
<Avatar server:defer>
  <GenericAvatar slot="fallback" />
</Avatar>

さらなる情報は公式サイトを参照してください。

Simplified prerendering

Astro v5 ではstatichybridの出力形式がstaticに統合されました。これは、actionや Server Islandsの使用に必要な設定が複雑化したため、わかりやすくするために行われました。

staticではデフォルですべてのページが静的に生成されますが、export const prerender = falseを指定することで動的なページを生成することも可能です。

型付き環境変数

環境変数にzodを使用して型を付けたり、デフォルト値を指定することができるようになりました。 使用できるコンテキストを制限したり、アクセス権を設定することも可能です。

// astro.config.mjs
import { defineConfig, envField } from 'astro/config'

export default defineConfig({
  env: {
    schema: {
      API_URL: envField.string({ context: "client", access: "public", optional: true }),
      PORT: envField.number({ context: "server", access: "public", default: 4321 }),
      API_SECRET: envField.string({ context: "server", access: "secret" }),
    }
  }
})

利用する際はastro/clientastro/serverからインポートします。クライアントコンポーネントからはastro/clientのみアクセスできます。

import { API_URL } from 'astro/client'
import { PORT, API_SECRET } from 'astro/server'

詳しくは公式サイトを参照してください。

Vite 6

つい先日リリースされた Vite 6 にも対応しています。

その他個人的に注目している新機能

Astro Blog では取り上げられていないものの、個人的に注目している機能についても紹介します。

import.meta.env.MODE

--modeフラグを使用することでimport.meta.env.MODEを指定できるようになりました。これはastro.config.mjsでもアクセスできるので、開発環境と本番環境で異なる設定を行うことができます。 astro dev"development"astro build"production"がデフォルトで設定されます。

さらに、.env.development.env.productionの切り替えも行われるので、環境ごとに異なる環境変数を設定することができます。

tsconfig.jsonの変更

Astroが推奨するtsconfig.jsonの設定が変更されました。

従来はenv.d.tsに以下のように書いていました。

/// <reference types="astro/client" />
/// <reference path="../.astro/env.d.ts" />
/// <reference path="../.astro/actions.d.ts" />

Astro v5 ではtsconfig.jsonに以下のように記述するようになりました。

  {
    "extends": "astro/tsconfigs/base",
+   "include": [".astro/types.d.ts", "**/*"],
+   "exclude": ["dist"]
  }

Markdownの改善

Markdownでの画像の読み込みが改善されました。同じフォルダ内に配置された画像に対して標準構文が使えるようになりました。

<!-- 従来 -->
![alt text](./image.png)

<!-- Astro v5 -->
![alt text](image.png)

Content Collection の JSON Schema 生成

Content Collection のスキーマからJSON Schemaを生成する機能が追加されました。これをエディタなどに登録することでJSONの入力が補完されるようになります。

.vscode/settings.json

{  
  "json.schemas": [
    {
      "fileMatch": ["/src/content/authors/*.json"],
      "url": "/.astro/collections/authors.schema.json"
    },
  ]
}

また、Content Intellisenseという機能も実験的に追加されています。これを有効にすると.md, .mdx, .mdocファイル内でIntellisenseが有効になります。

CSRF Protection

Origin ヘッダーをチェックして、CSRF攻撃を防ぐための機能が追加されました。これはデフォルトで有効になっています。

Astro Integration 同士の通信

Astro Integration 同士の相互呼び出しが可能になりました。これにより、複数のAstro Integration を組み合わせるIntegrationが作成できます。

langAlias for shiki

Markdownのコードブロックのシンタックスハイライトを提供しているshikiの設定にlangAliasが追加されました。これにより、javascriptcjsとして指定することができます。

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  markdown: {
    shikiConfig: {
      langAlias: {
        cjs: 'javascript',
      },
    },
  },
});

Experimental features

現時点 (2024/12/8) ではまだ実験的な機能として以下の機能が追加されています。

Container API

Container APIを使うと Astro コンポーネントを個別にレンダリングできます。これによりコンポーネントのテストが容易になります。

将来的にはServer側でも利用できるようになる予定だそうです。

Astro Container API (experimental)
Astro Container API (experimental) favicon https://docs.astro.build/en/reference/container-reference/
Astro Container API (experimental)

SVG Component

svgファイルをコンポーネントとして読み込める機能です。色やサイズを指定できます。

---
import Logo from '../assets/logo.svg';
---

<Logo width={64} height={64} fill="currentColor" />

sizeプロパティを指定することで、widthheightを同時に指定することもできます。

Experimental SVG components
Experimental SVG components favicon https://docs.astro.build/en/reference/experimental-flags/svg/
Experimental SVG components

Responsive Images

<Image /><Picture />コンポーネントに渡した画像からレスポンシブな画像を自動的に生成する機能です。

---
import { Image, Picture } from 'astro:assets';
import myImage from '../assets/my_image.png';
---
<Image src={myImage} alt="A description of my image." layout='responsive' width={800} height={600} />
<Picture src={myImage} alt="A description of my image." layout='full-width' formats={['avif', 'webp', 'jpeg']} />

まとめ

以上個人的に気になったAstro v5の新機能を紹介しました。まだまだ実験的な機能も多いので、これからの発展が楽しみです。