2026年10月06日

Astro v5→v7 にアップグレードしました

はじめに

2026年1月、このサイトのリニューアルに伴い、フレームワークとしてAstroを導入しました。当時のAstroのバージョンは5.17.2でした。

あれから10か月。
なんと、メジャーバージョンが2回もリリースされていたようで、現在の最新バージョンは7.3.5!

ということで、次のメジャーアップデートがやってくる前に、最新バージョンへのアップグレードを実施することにします。うろ覚えな点もありますが、実施後にまとめたメモがこちらになります。

アップグレードの手順

実際に行った手順は以下の通りです。

  1. 作業ブランチを作成
  2. 一思いに、最新バージョン(v7)にアップグレード
  3. 公式の移行ガイド(v5→v6)に則り、適宜修正
  4. 公式の移行ガイド(v6→v7)に則り、適宜修正
  5. ビルドが通るかチェックして、動作確認
  6. メインブランチにマージして完了

今回はシンプルな個人サイトなので、v5→v7に一気に上げることにしました。
慎重に進めたいプロジェクトや、1ステップの負荷を小さくしたい場合は、まずはv5→v6に上げ、そのあとでv6→v7に上げるような段階を踏むパターンもあると思います。

さっそく、アップグレード(v5→v7)

作業ブランチにて、アップグレードを実施。コマンドはnpmで以下の通りです。

Terminal window
npx @astrojs/upgrade

公式の移行ガイドでも上記のコマンドが記載されていますが、段階を踏んでアップグレードする場合は、バージョンを指定する必要があるので注意してください。

移行ガイド(v5→v6)を読む

Astro v6へのアップグレード | Docshttps://docs.astro.build/ja/guides/upgrade-to/v6/

このガイドでは、Astro v5からAstro v6への移行方法を説明します。

順に読んでいき、自分のプロジェクトで必要そうな修正をしていきます。今回、実際に行った修正は以下の通りです。

Node の更新

Nodeの公式からインストーラーをダウンロードしてインストールしました。
しっかり古かったので、しっかり更新しました。


移行ガイド「依存関係のアップグレード」の章では、他は問題ないようでした。

コンテンツコレクション

今回の移行作業はここが肝でした。

コンテンツコレクション周りが大幅に変更されていました(*1)。
大きな変更だったので、公式ガイドのその他のページ(*2)も参考にしました。

実際に修正したのは以下の項目です。

  • src/content/config.tsをsrc/content.config.tsに変更
  • type定義を削除してloaderを定義
  • import { z } from "astro:content";をimport { z } from "astro/zod"に変更(*3)
  • slugプロパティをidプロパティに変更
  • entry.render()をrender(entry)の形に変更

src/content.config.ts

コレクション定義ファイルは以下のようなイメージです。

src/content.config.ts
import { glob } from "astro/loaders";
import { defineCollection } from "astro:content";
import { z } from "astro:content";
import { z } from "astro/zod";
export const collections = {
  pages: defineCollection({
  type: "content",
  loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/blog" }),
  schema: z.object({
title: z.string(),
pubDate: z.date(),
description: z.string(),
author: z.string(),
image: z.object({
url: z.string(),
alt: z.string()
}),
tags: z.array(z.string())
})
});

記事レンダー

記事の生成周りは以下のイメージです。

src/pages/posts/[...slug].astro
---
import { getCollection } from 'astro:content';
import { render } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug }, props: { post },
params: { slug: post.id }, props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
const { Content } = await render(post);
---

getDataEntryById()やgetEntryBySlug()を使用している箇所はありませんでした。

移行ガイドでは、他にも削除された項目やデフォルト値の変更などが大量にありましたが、影響を受けるものは特にありませんでした。

移行ガイド(v6→v7)を読む

Astro v7へのアップグレード | Docshttps://docs.astro.build/ja/guides/upgrade-to/v7/

このガイドでは、Astro v6からAstro v7への移行方法を説明します。

v5→v6と同様に、必要な修正をしていきます。実際に行った修正は以下の通りです。

Markdownプラグイン関連

移行ガイド「新しいデフォルトのMarkdownプロセッサー: Sätteri」周りです。
remarkやrehypeのプラグインをいろいろ利用していたため、このあたりでエラーや警告が出てくるようになりました。

「Unified」と「Sätteri」

以前までのバージョンでは、Markdownのプロセッサに「Unified」が使用されていましたが、v7からは、「Sätteri」が標準搭載になりました。

公式ガイドでは、Markdownのプロセッサとして「Unified」か「Sätteri」のいずれかをユーザーが選択して機能を拡張できる旨の記載がありました。機能面の主な違いは、「Sätteri」は高速、「Unified」は蓄積された豊富なリソースといった説明がされています(※)。

「Unified」の利点は今後「Sätteri」にも期待されると思いますので、「Unified」の選択は暫定措置と考えた方が良さそうです。

※公式ガイド「Markdownプロセッサの選択」

Markdownプロセッサ

Markdown形式のデータの変換や加工をする機能のことです。この機能により、Markdown形式からHTML形式に変換されたり、独自の処理を挟んで拡張することができます。

暫定対応編

markdown.remarkPlugins、markdown.rehypePlugins、markdown.remarkRehypeオプションが非推奨になりましたが、astro.config.mjsを見てみると……いろいろ詰め込んでありました。
このあたりの整理には時間がかかりそうなので、ひとまずは移行ガイド通りにunifiedを使い続ける方向で対処します。

@astrojs/markdown-remarkをインストールして、astro.config.mjsを以下のように修正しました。

astro.config.mjs
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
export default defineConfig({
markdown: {
processor: unified({
remarkRehype: {
// ....
},
remarkPlugins: {
// ....
},
rehypePlugins: {
// ....
},
}),
},
});

時間ができたときに、各オプションをひとつひとつ見直そうと思います……。

Sätteri移行編(準備中)

アップグレード完了後、実は移行済みです。そのうち追記します……。


v7の移行では、他に影響を受けそうなものはありませんでした。
v6と比べるとページのスクロール量が圧倒的に違ったので、移行ガイドに目を通すのが非常にラクでした。

ビルドチェック

やっとここまできました……。

恐る恐るビルドしてみたところ、大量の警告が流れていきました。

Terminal window
[WARN] [vite] [MODULE_LEVEL_DIRECTIVE] The semantics of the module level directive "use astro:head-inject" in "xxxxx" may not be preserved when bundling.
╭─[ xxxxx.mdx?astroPropagatedAssets:2:6 ]
│
2 │ "use astro:head-inject";
│ ────────────┬───────────
│ ╰───────────── module level directive may not be preserved
│
│ Help: For more information, see https://rolldown.rs/in-depth/directives#other-directives

上記のような警告が、おそらくはMarkdownのファイル数あったのかもしれません(数えられなかったので不明)。

これはviteの警告で、無視して問題はないそうです。個人で対処できるものではなく、Astro側の対応を待つしかないとのことでした。

しかし、あまりにも大量で気分がよろしくありません。一時的に、この警告メッセージを非表示にすることにします。

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
  vite: {
    // Vite/Rolldown警告メッセージを非表示にするための暫定措置
    // ※Astro対応待ち【Astro 7.3.5 現在】
    build: {
      rollupOptions: {
        onwarn(warning, defaultHandler) {
          if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "MODULELEVELDIRECTIVE") return;
          defaultHandler(warning);
        },
      },
    },
  },
});

これできれいさっぱり、警告が消え失せました。

ビルドが通ったところで、動作確認をして、以前と変わりなく動作することを確かめます。問題なければ、ブランチをマージして、完了です。

おわりに

記憶が抜け落ちている箇所も多々ありそうですが、このような感じで完了しました。

流行りのシステムをAI駆動で存分に試したいという欲求ありきでAstro導入に至ったので、Astroについてほとんど何も理解しないまま、AIの勢いで今日まで来てしまっていました(ちょっと罪悪感あり…)。 そのため、小さなことで「?」となってしまい、完了までの時間はかかりませんでしたが、終わった直後は疲労困憊でした。 ただ、こうして振り返ってみると、意外と簡単に済んだような気がします。理解が深まった証拠でしょうか。

これで次のアップグレードも怖くありません。が、AIの進化をみていると、次こそワンクリックですべて完了するような状況に到達しているのかな、なんて思ったりもします。そのような状況にいるからこそ、時間を割いてAstroと向き合って、素直に楽しかったです。