はじめに
長らく Hugo で運用してきた本ブログですが、今後の 3D コンテンツ(Three.js / R3F)の積極的な統合を見据え、Astro への移行を決意しました。
その第一歩として、環境構築から初期ビルドまでに遭遇した
- 「Windows 特有の挙動」
- 「Markdown 互換性」の罠
についての記録を残しておきます。
1. 開発環境のセットアップと Windows の壁
Astro を新規導入するべく、意気揚々とプロジェクトの初期化(create-astro)を行い、いざ開発サーバーを立ち上げようとした矢先、Windows 環境特有の洗礼を受けることになりました。
1.1 「‘astro’ は内部コマンドまたは外部コマンドとして認識されていません」の罠
npm install 自体は特にエラーを吐くこともなく正常終了した(ように見えた)にもかかわらず、npm run dev を実行すると無情にもエラーが表示され、サーバーが起動しません。
| 項目 | 内容 |
|---|---|
| 症状 | npm run dev 実行時、node_modules/.bin/astro へのパスが解決できずエラーになる。 |
| 主な原因 | Windows におけるシンボリックリンク生成の失敗、または package-lock.json とキャッシュの不整合。 |
| 解決策 | 環境の完全リセット(既存の依存関係をすべて破棄して再構築)。 |
-
症状の深掘り 本来、npm run dev を実行すると package.json の scripts を経由して、ローカルの node_modules/.bin/astro が呼び出されます。しかし、ターミナル側でこの実行ファイルへのパスを解決できず、コマンドが見つからないとしてプロセスが強制終了してしまいます。
-
原因:Windows のパス解決とキャッシュの迷宮 この現象は、主に以下の要素が複合して引き起こされます。
- .bin へのコマンド生成の失敗: npm はインストール時、node_modules/.bin 配下に実行用のスクリプト(Windows の場合は .cmd ファイル等)を生成します。しかし、Windows 環境下では権限の問題やファイルシステムの都合で、これが正常に作られない・あるいは見失われるケースがあります。
- package-lock.json とキャッシュの不整合: 過去のプロジェクトの依存関係の残骸や、以前別の開発をしていた際の npm キャッシュが干渉し、依存ツリーが壊れた状態でロックされてしまっている状態です。
-
対策:環境の「完全リセット」による解決 このようなパスや依存関係の絡れには、小手先の修正ではなく「環境のクリーンアップ」を行うのが最も確実かつ時短になります。以下の3ステップを実行し、正常化させました。
- 依存関係の破棄: プロジェクト直下にある node_modules フォルダと package-lock.json を削除し、壊れたツリーを一旦リセットします。
- キャッシュの強制クリア: npm cache clean –force コマンドを実行し、npm が内部で抱え込んでいる古いキャッシュデータを強制的に消去します。これにより、次回インストール時に必ずクリーンなパッケージを取得できるようになります。
- 再構築: 改めて npm install を実行し、依存関係をゼロから構築し直します。
💡 Tips: Windows Terminal の管理者権限
Windows 環境において、npm がシンボリックリンクやコマンド群を正しく生成できない場合、ターミナルの権限不足が隠れた原因となっていることが多々あります。 PowerShell や Windows Terminal を「管理者として実行」した上で上記のクリーンアップとインストールを行うことで、ファイル生成周りのサイレントなトラブルを未然に防ぐことができます。
2. Hugo からの Markdown 移行とレンダリングエラー
開発環境が立ち上がり、いざ Hugo 時代に書き溜めた Markdown 資産を Astro の src/content/ に移行したところ、今度はビルドエラーや画面のレンダリング崩れが頻発しました。主に「シンタックスハイライト」と「ファイル名」の2点が鬼門となりました。
2.1 Shiki シンタックスハイライターの厳格なパースによるクラッシュ
Astro は標準のシンタックスハイライターとして、非常に美しく高機能な Shiki を採用しています。しかし、これが原因で思わぬ落とし穴にハマりました。
-
症状の深掘り 開発サーバーを起動して記事一覧までは表示されるものの、個別の記事ページにアクセスするとサーバー側でパースエラー(500エラー)を吐く、あるいは画面が真っ白になってしまいます。本番ビルド(astro build)を実行しても、特定の箇所でプロセスが中断してデプロイできない状態に陥りました。
-
原因:Hugo(Chroma)と Astro(Shiki)の許容度の違い Hugo の標準ハイライター(Chroma 等)は、未知の言語タグが指定されても「単なるプレーンテキスト」としてフォールバックし、エラーを出さずに処理してくれていました。 しかし、Astro 標準の Shiki は非常に厳格です。過去の MSX や Commodore 64 などのレトロPC関連の記事で指定していた basic や、WebAssembly の検証コードで使っていた wat といった、Shiki がデフォルトで読み込んでいない言語タグに遭遇すると、パースできずに致命的なエラー(Fatal Error)として処理を止めてしまっていたのです。
-
対策:言語タグの正規化と設定の調整 根本的な解決として、以下の対応を行いました。
- Markdown 側の修正: エラーの元となっている非標準的な言語タグを検索し、Shiki がサポートしている一般的なタグ(または単なる text)へ一括置換しました。
- Astro 側の設定(必要な場合): どうしても独自の言語やマイナーな言語をハイライトさせたい場合は、astro.config.mjs の markdown.shikiConfig にカスタム言語を読み込ませるか、エラー時のフォールバック設定を追加することでレンダリングを正常化させることができます。
2.2 日本語ファイル名によるビルドパイプラインの不安定化
もうひとつの罠は、Markdown ファイルの「命名規則」に関するものでした。
-
症状の深掘り Windows のローカル環境では問題なく記事が表示されているにもかかわらず、Netlify 等へデプロイする際のビルドプロセスで、特定の記事だけが「Not Found」としてスキップされたり、読み込みエラーでデプロイが失敗したりする現象が発生しました。
-
原因:OS間のエンコーディングとパス解決の差異 Hugo 時代に「2025-09-25-〇〇の解説.md」のように、ファイル名に日本語(全角文字)を含めていたことが原因です。Windows のローカルファイルシステムではよしなに解釈されても、Linux ベースの CI/CD 環境(ビルドサーバー)上では、URL エンコーディングの不一致やマルチバイト文字の扱いの違いにより、正しいファイルパスとして解決できなくなっていました。
-
対策:ケバブケース(kebab-case)への完全統一 今後の運用も踏まえ、すべての Markdown ファイル名を 半角英数字とハイフンのみのケバブケース に一括でリネームしました。
- ❌ 変更前: 2026-02-14-React Three Fiberでルービックキューブ.md
- ⭕ 変更後: 2026-02-14-r3f-rubiks-cube.md
これにより、Astro の Content Collections 機能によるデータ取得も安定し、ファイルシステムやビルド環境に依存しない堅牢な読み込みが保証されるようになりました。
3. 今後の課題と展望:アイランド・アーキテクチャと 3D コンテンツの統合
今回の Hugo から Astro への移行は、単なる静的サイトジェネレーター(SSG)の乗り換えではありません。最大の目的は、Astro の強力な武器であるアイランド・アーキテクチャ(Islands Architecture)を活用し、ブログ記事とフロントエンドの 3D コンテンツをシームレスに統合することにあります。
-
静的コンテンツと動的コンポーネントの共存 Hugo のような従来の SSG では、React Three Fiber(R3F)や Babylon.js を使ったリッチな 3D アプリケーションを記事内に直接マウントし、コンポーネントとして管理するにはビルドや設計の面で限界がありました。 Astro を採用することで、ブログのテキストやレイアウト部分は極めて軽量な静的 HTML として高速に配信しつつ、必要な箇所(3Dのキャンバス)だけを「インタラクティブな島」として独立させ、クライアント側で JavaScript を実行(ハイドレーション)させることが可能になります。
-
「Noise 入門」シリーズのインタラクティブ化 現在執筆・構築を進めている「Noise 入門」シリーズのようなプロシージャル生成を扱う大規模な記事群では、この仕組みが不可欠です。 今後は単なるコードスニペットや実行結果の画像(スクショ)を貼るだけでなく、読者がブラウザ上で直接パラメータを操作できるノイズのデモ画面や、R3F で構築した 3D コンポーネント(以前開発したルービックキューブのようなインタラクティブなオブジェクト)を、そのまま記事の一部として埋め込んでいく予定です。
まずはこの新環境でのビルド・デプロイパイプライン(Netlify)を安定して回すことを最優先とし、次の一手として、Astro 上への React コンポーネントの導入と、3D キャンバスの段階的な統合テストへ移行していきます。
💬 コメント