古くなっていたAstro 6を7へ更新した記録|変更点と詰まったところ

contents9
  1. 01まずは公式のアップグレードコマンドを実行
  2. 02最初にWranglerのバージョンで止まった
  3. 03Markdownの処理方式が変わった
  4. 04以前は通っていたHTMLコメントがエラーになった
  5. 05構造化データ内のAstro参照も移動した
  6. 06Astro 7で大きく変わったところ
  7. 07更新時に確認したい順番
  8. 08更新してみた感想
  9. 09参考文献

このブログのAstroが6.4のままになっていたので、Astro 7へ更新しました。

Astro 7.0自体は2026年6月22日に正式リリースされています。更新した時点では7.3.4まで出ており、少し遅れて追いつく形になりました。

結論から書くと、公式のアップグレードコマンドだけでは終わりませんでした。Astro本体と公式インテグレーションは更新できたものの、Wranglerのバージョン、Markdown処理、以前は通っていたテンプレート構文などを追加で直しています。

まずは公式のアップグレードコマンドを実行

このプロジェクトではpnpmを使っているため、次のコマンドを実行しました。

pnpm dlx @astrojs/upgrade

更新対象として表示されたのは次の4つです。

パッケージ更新前更新後
astro6.4.47.3.4
@astrojs/check0.9.90.9.10
@astrojs/cloudflare13.6.114.3.3
@astrojs/mdx6.0.28.0.2

確認画面で続行すると、公式パッケージの更新と依存関係のインストールまでは自動で進みました。

ただし、公式ガイドにも「ほかの依存関係は別途更新が必要になる場合がある」とあります。今回も、ここからが本番でした。

最初にWranglerのバージョンで止まった

更新直後に開発サーバーを起動すると、Astroの設定を読み込む段階で止まりました。

pnpm dev

表示された内容は、インストール済みのWrangler 4.97.0では、@cloudflare/vite-pluginが要求する^4.136.3を満たしていないというものです。

The installed version of Wrangler (4.97.0) does not satisfy
the peer dependency required by @cloudflare/vite-plugin (^4.136.3).

Astroのアップグレードツールは公式インテグレーションを更新してくれますが、プロジェクト側で直接追加していたWranglerまでは必要な版へ揃えてくれませんでした。

今回は次のように更新しています。

pnpm add -D wrangler@^4.136.3

その後、pnpm devは起動するようになりました。Cloudflareアダプターを使っている場合は、Astro本体だけでなく、@astrojs/cloudflare、@cloudflare/vite-plugin、Wranglerの要求バージョンを一緒に見る必要があります。

Markdownの処理方式が変わった

次に引っかかったのがastro.config.mjsのMarkdown設定です。

Astro 7では、MarkdownとMDXの標準processorが、unified(remark/rehype)からRust製のSätteriへ変わりました。remarkやrehypeのプラグインを使っていないサイトなら、そのままで問題ない場合が多いようです。

このブログでは、外部リンクへtarget="_blank"と安全用のrel属性を付けるため、rehype-external-linksを使っています。そのため、従来のunified pipelineを明示的に残しました。

まず必要なパッケージを追加します。

pnpm add @astrojs/markdown-remark

設定は次の形に変更しました。

import { unified } from '@astrojs/markdown-remark';
import rehypeExternalLinks from 'rehype-external-links';

export default defineConfig({
  markdown: {
    processor: unified({
      rehypePlugins: [
        [rehypeExternalLinks, {
          target: '_blank',
          rel: ['noopener', 'noreferrer'],
        }],
      ],
    }),
  },
});

Astro 7でも旧設定のmarkdown.remarkPluginsやmarkdown.rehypePluginsは当面動きますが、@astrojs/markdown-remarkのインストールが別途必要です。今回は今後の形が分かりやすいprocessor: unified()へ移しました。

以前は通っていたHTMLコメントがエラーになった

Astro 7では.astroコンパイラーがGo製からRust製へ書き直され、構文チェックが以前より厳格になっています。公式発表では、タグの閉じ忘れや不完全な属性などを黙って補正せず、エラーとして扱うようになったと説明されています。

このブログでは、三項演算子の分岐直後に置いていたHTMLコメントでビルドが止まりました。

{
  posts.length > 0 ? (
    <PostList posts={posts} />
  ) : (
    <!-- No Posts Message -->
    <div class="no-posts">記事がありません</div>
  )
}

分岐の返り値は単一の要素である必要があるため、今回はコメントを削除しました。

{
  posts.length > 0 ? (
    <PostList posts={posts} />
  ) : (
    <div class="no-posts">記事がありません</div>
  )
}

同じ書き方がカテゴリ一覧と月別アーカイブに残っていたため、両方を修正しています。astro checkでは見つからず、実際のastro buildで初めて止まった点も注意が必要でした。

構造化データ内のAstro参照も移動した

/aboutのプリレンダーでは、次のエラーが出ました。

ReferenceError: Astro is not defined

原因になったのは、テンプレート側のset:htmlへ渡す式の中で、Astro.urlとAstro.siteを参照していた部分です。

<script
  is:inline
  type="application/ld+json"
  set:html={JSON.stringify({
    url: new URL(Astro.url.pathname, Astro.site).toString(),
  })}
/>

Astro 7のビルドでは、この式が別の関数へ抽出された際にAstroがスコープ外になっていました。そこで、frontmatter側でJSON文字列を先に作る形へ変更しました。

---
const structuredData = JSON.stringify({
  url: new URL(Astro.url.pathname, Astro.site),
});
---

<script
  is:inline
  type="application/ld+json"
  set:html={structuredData}
/>

この修正後は/about/index.htmlも正常にプリレンダーされています。これは公式移行ガイドに独立した破壊的変更として書かれているものではなく、今回のプロジェクトで実際に起きた互換性問題です。

Astro 7で大きく変わったところ

今回のサイトで直接触った部分以外にも、Astro 7にはいくつか大きな変更があります。

Vite 8とRolldown

開発サーバーと本番ビルドがVite 8へ更新されました。Vite 8ではRust製bundlerのRolldownが使われています。

一般的なAstroサイトは設定変更なしで移行できるとされていますが、独自のViteプラグイン、rollupOptions、Vite内部APIに依存する設定がある場合は、Vite 8側の移行内容も確認した方が安全です。

Rust製コンパイラーとMarkdown pipeline

.astroコンパイラーに加え、標準のMarkdown/MDX処理もRustベースになりました。Astro公式のベンチマークでは、サイト全体のビルド時間が15〜61%短縮したとされています。

ただし、この数値は公式が複数サイトで測った結果です。記事数やプラグイン構成で差が出るため、自分のサイトでも同じ割合で速くなるとは限りません。

空白文字の扱い

HTML圧縮の既定値がtrueから'jsx'へ変わり、インライン要素間の改行が空白として残らない場合があります。

<span>hello</span>
<em>world</em>

Astro 6ではhello worldだった箇所が、Astro 7ではhelloworldになる可能性があります。必要な箇所では明示的に空白を入れます。

<span>hello</span>{' '}<em>world</em>

従来の挙動をサイト全体で維持するなら、astro.config.mjsでcompressHTML: trueを指定する方法もあります。

src/fetch.tsが予約ファイルになった

Astro 7ではAdvanced Routingが追加され、src/fetch.tsとsrc/fetch.jsが特別なファイル名になりました。すでに別用途で同名ファイルを置いている場合は、名前を変えるか、fetchFile: nullで無効にする必要があります。

開発サーバーのバックグラウンド実行

astro dev --backgroundで、開発サーバーを管理されたバックグラウンドプロセスとして起動できるようになりました。

pnpm exec astro dev --background
pnpm exec astro dev status
pnpm exec astro dev logs
pnpm exec astro dev stop

AIコーディングエージェント上では自動的にバックグラウンドモードになる場合があります。今回、起動ログが通常と少し違って見えたのもこの仕組みでした。

更新時に確認したい順番

今回の経験から、Astroのメジャーアップデートでは次の順番で見ると原因を切り分けやすいです。

  1. pnpm dlx @astrojs/upgradeでAstroと公式インテグレーションを更新する
  2. pnpm devで設定ファイルとpeer dependencyの問題を見る
  3. pnpm checkで型とAstroファイルを検査する
  4. pnpm buildで全ページのコンパイルとプリレンダーを確認する
  5. 主要ページをブラウザーで開き、インライン要素の空白やレイアウトを目視する
  6. Cloudflare Pagesなど、本番と同じ環境でもプレビューする

確認用の基本コマンドは次の2つです。

pnpm check
pnpm build

pnpm devが起動しただけでは、アクセスしていない動的ルートやプリレンダー時の問題までは分かりません。今回も、コメント構文とAstro is not definedはビルドを実行して初めて見つかりました。

更新してみた感想

Astro 6から7への更新は、アプリ全体を書き直すような大移行ではありませんでした。ただし、Cloudflare、MDX、rehypeプラグインまで組み合わせていると、アップグレードコマンドを1回実行して終わりとはいきません。

特に重要だったのは、エラーをひとまとめに「Astro 7が壊れた」と考えないことでした。Wranglerは依存バージョン、Markdownはprocessor変更、HTMLコメントはコンパイラーの厳格化、構造化データはプリレンダー時のスコープと、それぞれ原因が異なります。

最終的にはpnpm checkがエラー0件になり、pnpm buildも全ページ完走しました。少し手間はかかりましたが、古い版を抱えたままにせず、移行時に出た問題を一度整理できたのでよかったと思います。

参考文献

shareTwitterFacebook