Gatsbyからの移行
ここでは、移行を始める際に役立つ主要な概念と移行戦略を紹介します。詳しくはドキュメント全体やDiscordコミュニティをご活用ください。
GatsbyとAstroの類似点
セクションタイトル: GatsbyとAstroの類似点GatsbyとAstroには、プロジェクト移行を容易にするいくつかの共通点があります:
-
.astro
ファイルの構文はJSXとよく似ています。Astroの記法は馴染みがあるはずです。 -
AstroにはMarkdownのネイティブサポートがあり、MDXを利用するインテグレーションも用意されています。既存のMarkdownプラグインの多くをそのまま利用できます。
-
AstroにはReactコンポーネントを利用する公式インテグレーションがあります。AstroではReactファイルの拡張子を
.jsx
または.tsx
にする必要があります。 -
AstroはインストールNPMパッケージをサポートしており、Reactライブラリも含まれます。多くの既存の依存関係はAstroでも正常に動作します。
-
Gatsbyと同様に、AstroプロジェクトもSSGを選択できるほか、ページ単位の事前レンダリングを伴うSSRに対応しています。
GatsbyとAstroの主な相違点
セクションタイトル: GatsbyとAstroの主な相違点GatsbyサイトをAstroで再構築する際には、次のような重要な違いに気付くでしょう。
-
GatsbyプロジェクトはReactの単一ページアプリケーションで、
index.js
をプロジェクトのルートとして使用します。Astroプロジェクトはマルチページサイトで、index.astro
はホームページです。 -
Astroコンポーネントは、ページテンプレートを返すようにexportされた関数で書かれていません。代わりに、コードフェンス(
---
)でJavaScriptコードを区切って、生成するHTMLのためのコードを分けます。 -
ローカルファイルデータの取得: GatsbyはGraphQLを使用してプロジェクトファイルからデータを取得します。AstroではESMインポートとトップレベル
await
関数(例:import.meta.glob()
、getCollection()
)でファイルからデータをインポートします。必要ならAstroプロジェクトにGraphQLを手動で追加できますが、デフォルトでは含まれていません。
GatsbyプロジェクトをAstroに変換する
セクションタイトル: GatsbyプロジェクトをAstroに変換する各プロジェクトの移行手順は様々ですが、GatsbyからAstroへ変換する際に共通して行う作業があります。
新しいAstroプロジェクトの作成する
セクションタイトル: 新しいAstroプロジェクトの作成するパッケージマネージャでcreate astro
コマンドを実行してAstroのCLIウィザードを起動するか、Astro Theme Showcaseからコミュニティテーマを選択します。
create astro
コマンドに--template
引数を渡すと、公式スターター(例:docs
、blog
、portfolio
)のいずれかで新しいAstroプロジェクトを作成できます。また、GitHub上の既存Astroリポジトリから新規プロジェクトを開始することも可能です。
# Astro CLIウィザードを実行npm create astro@latest
# 公式スターターを指定して作成npm create astro@latest -- --template <example-name>
# Astro CLIウィザードを実行pnpm create astro@latest
# 公式スターターを指定して作成pnpm create astro@latest -- --template <example-name>
# Astro CLIウィザードを起動yarn create astro@latest
# 実際のスターターテンプレートを使用して新しいプロジェクトを開始yarn create astro@latest -- --template <example-name>
次に、既存のGatsbyプロジェクトのファイルをsrcの外側にある別フォルダーへコピーし、新しいAstroプロジェクトへ移行します。
公式スターターテンプレートの一覧は公式スターターテンプレートを参照してください。IDX、StackBlitz、CodeSandbox、またはGitpodで新規プロジェクトを開くためのリンクもあります。
インテグレーションのインストールする(任意)
セクションタイトル: インテグレーションのインストールする(任意)GatsbyプロジェクトをAstroへ変換する際、以下のようなAstroのオプションインテグレーションが役立つことがあります。
-
@astrojs/react: 新規Astroサイトで既存のReact UIコンポーネントを再利用するか、Reactコンポーネントで書き続けることができます。
-
@astrojs/mdx: Gatsbyプロジェクトの既存のMDXファイルを持ち込むか、新規AstroサイトでMDXを使用することができます。
ソースコードをsrc
に配置する
セクションタイトル: ソースコードをsrcに配置するAstroのプロジェクト構造に従って、次の手順でファイルを整理します。
-
削除 Gatsbyの
public/
フォルダ。Gatsbyはビルド出力を
public/
ディレクトリに生成しますが、Astroはデフォルトでdist/
を使用します。そのためpublic/
は安全に削除できます。 -
リネーム Gatsbyの
static/
フォルダをpublic/
、そしてAstroのpublic/
フォルダとして使用してください。Astroは静的アセット用に
public/
フォルダーを使用します。既存のAstropublic/
へstatic/
の内容をコピーしても構いません。 -
コピーまたは移動 Gatsbyの
components
、pages
などの他のファイルとフォルダを、必要に応じてAstroのsrc/
フォルダへ配置してください。Astroのプロジェクト構造を遵守して、ソースコードをsrc
に配置してください。Astroの
src/pages/
フォルダは、.astro
、.md
、.mdx
ファイルからサイトのページと記事を生成するための特殊なフォルダです。Astro、Markdown、MDXファイルのルーティングを設定する必要はありません。その他のフォルダは任意のため、
src/
フォルダの内容をどのように配置するかは任意です。Astroプロジェクトで一般的なフォルダにはsrc/layouts/
、src/components
、src/styles
、src/scripts
があります。
ヒント:JSXファイルから.astro
ファイルへの変換する
セクションタイトル: ヒント:JSXファイルから.astroファイルへの変換するここでは、Gatsbyの.js
コンポーネントを.astro
コンポーネントに変換するためのいくつかの手順を説明します。
-
既存Gatsbyコンポーネントの
return()
部分のみをHTMLテンプレートとして使用してください。 -
<Link to="">
・{children}
・className
などGatsby/JSX構文をAstro構文またはHTML標準に変換してください。 -
import
文を含んだ必要なJavaScriptは”コードフェンス” (---
)内へ移動してください。注意: 条件付きレンダリング用のJavaScriptは、AstroではHTMLテンプレート内に直接書くことが多いです。 -
Astro.props
(EN)を使用して、以前にGatsby関数に渡された追加のpropsを参照してください。 -
インポート済みコンポーネントをAstroに変換するか検討してください。公式Reactインテグレーションを使えばAstroファイル内で既存Reactコンポーネントを利用できますが、インタラクティブ性が不要なら
.astro
へ変換して軽量化できます。 -
GraphQLクエリは削除し、
import
やimport.meta.glob()でローカルファイルを読み込ます。
Gatsby Blogスターターを段階的に変換した例も参照してください。
.jsx
と.astro
の比較する
セクションタイトル: .jsxと.astroの比較する以下のGatsbyコンポーネントと対応するAstroコンポーネントを比較してください:
import * as React from "react"import { useStaticQuery, graphql } from "gatsby"import Header from "./header"import Footer from "./footer"import "./layout.css"
const Component = ({ message, children }) => { const data = useStaticQuery(graphql` query SiteTitleQuery { site { siteMetadata { title } } } `) return ( <> <Header siteTitle={data.site.siteMetadata.title} /> <div style={{ margin: `0`, maxWidth: `960`}}>{message}</div> <main>{children}</main> <Footer siteTitle={data.site.siteMetadata} /> </> )}
export default Component
---import Header from "./Header.astro"import Footer from "./Footer.astro"import "../styles/stylesheet.css"import { site } from "../data/siteMetaData.js"const { message } = Astro.props---<Header siteTitle={site.title} /> <div style="margin: 0; max-width: 960;">{message}</div> <main> <slot /> </main><Footer siteTitle={site.title} />
レイアウトファイル移行する
セクションタイトル: レイアウトファイル移行するレイアウトファイルをAstroレイアウトコンポーネントに変換するには、Gatsbyのレイアウトやテンプレートから始めてみてください。
Astroの各ページには必ず <html>
・<head>
・<body>
タグが必要なため、複数ページで同じレイアウトファイルを再利用するのが一般的です。Astroではページコンテンツ差し込みに Reactの {children}
ではなく <slot />
を使用し、import
文も不要です。Gatsbyのlayout.js
やテンプレートにはこれらが含まれていません。
標準的なHTMLテンプレートと<head>
タグへの直接アクセスする例:
<html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <title>Astro</title> </head> <body> <!-- 既存のレイアウトテンプレートで`<slot />`要素を囲んでください。--> <slot /> </body></html>
追加でサイトメタデータを含めたい場合は、Gatsbyのsrc/components/seo.js
のコードを再利用できます。注意: Astroでは<Helmet>
や<Header>
を使わずに<head>
を直接記述します。ページコンテンツを分離して整理するには、コンポーネントを<head>
内でインポートして使用することができます。
ページと投稿の移行する
セクションタイトル: ページと投稿の移行するGatsbyでは ページや投稿 がsrc/pages/
内、またはcontent
などsrc
の外に置かれている場合があります。Astroでは コンテンツコレクション を使わない限り、すべてのページコンテンツをsrc/
内に配置する必要があります。
Reactページ
セクションタイトル: Reactページ既存のGatsby JSX(.js
)ページはJSXファイルから.astroページへ変換する必要があります。AstroではJSXページファイルをそのまま使用できません。
変換した.astroページはsrc/pages/
に置き、ファイルパスに基づいてページルートが自動生成されます。
MarkdownとMDXページ
セクションタイトル: MarkdownとMDXページAstroはMarkdownをネイティブサポートし、MDX用のオプション統合も提供しています。既存のMarkdownとMDXファイルを再利用できますが、フロントマターにAstro専用のlayout
プロパティを追加するなどの調整が必要な場合があります。これらのファイルもsrc/pages/
に置けば自動的にファイルベースルーティングを利用できます。
あるいはAstroのコンテンツコレクションを使ってコンテンツを管理し、自分で取得して動的にページを生成することもできます。
テストの移行する
セクションタイトル: テストの移行するAstroは生のHTMLを出力するため、ビルド後の出力を使用したE2Eテストができます。旧Gatsbyサイトのマークアップが再現できれば、既存のエンドツーエンドテストがそのまま動作する場合があります。JestやReact Testing LibraryなどをインポートしてReactコンポーネントをテストできます。
詳しくはテストガイドを参照してください。
設定ファイルの再利用する
セクションタイトル: 設定ファイルの再利用するGatsbyにはルーティングやメタデータを含むトップレベル設定ファイルが複数あり、ルーティングに使用されます。Astroではこれらのgatsby-*.js
ファイルを使用しませんが、内容を再利用できる場合があります。
-
gatsby-config.js
:src/data/siteMetadata.js
(またはsiteMetadata.json
)にsiteMetadata: {}
を移動して、ページレイアウトにサイト(タイトル、説明、ソーシャルアカウントなど)に関するデータをインポートします。 -
gatsby-browser.js
: ここで使用されているものは、主要レイアウトの<head>
タグに直接追加することを考慮してください。 -
gatsby-node.js
: Astroでは独自のノードを作成する必要はありませんが、このファイルのスキーマを確認して、Astroプロジェクトで型を定義するのに役立つかもしれません。 -
gatsby-ssr.js
: AstroでSSRを使用する場合、astro.config.mjs
に直接SSRアダプターを追加して構成してください。
参考: Astro構文への変換する
セクションタイトル: 参考: Astro構文への変換する以下はGatsby特有の構文をAstroに変換するいくつかの例です。Astroコンポーネントの書き方におけるAstroとJSXの違いも参照してください。
Gatsby LinksをAstroに変換する
セクションタイトル: Gatsby LinksをAstroに変換するGatsbyの<Link to="">
、<NavLink>
などのコンポーネントをHTMLの<a href="">
タグに変換します。
<Link to="/blog">Blog</Link><a href="/blog">Blog</a>
Astroにはリンク専用のコンポーネントはありませんが、独自の<Link>
コンポーネントを作ってもかまいません。<Link>
を他のコンポーネントのようにインポートして使用することができます。
---const { to } = Astro.props---<a href={to}><slot /></a>
Gatsby ImportsをAstroに変換する
セクションタイトル: Gatsby ImportsをAstroに変換する必要に応じて、ファイルのインポートを相対ファイルパスで正確に参照するように変更します。これにはインポートエイリアスを使用したり、相対パスを完全に書くこともできます。
注意: .astro
など一部のファイルは拡張子を省略できません。
---import Card from `../../components/Card.astro`;---<Card />
Gatsbyの{children}
をAstroに変換する
セクションタイトル: Gatsbyの{children}をAstroに変換するGatsbyの{children}
をAstroの<slot />
に変換します。Astroは{children}
を関数プロップとして受け取る必要なく、子要素を<slot />
で自動的にレンダリングします。
------export default function MyComponent(props) { return ( <div> {props.children} </div> );}
<div> <slot /></div>
Reactコンポーネントが複数の子要素を渡す場合は、named slotsを使用してAstroコンポーネントに移行できます。
特定の<slot />
の使用方法に関する詳しい説明は特定の<slot />
の使用方法を参照してください。
スタイリングを変換する
セクションタイトル: スタイリングを変換する必要に応じて、CSS-in-JSライブラリ(例:styled-components)をAstroで使用できるCSSオプションに置き換える必要があります。
必要なら、インラインスタイルオブジェクト(style={{ fontWeight: "bold" }}
)をインラインHTMLスタイル属性(style="font-weight:bold;"
)に変換するか、Astroの<style>
タグを使用してスコープCSSスタイルを記述します。
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div><div style="background-color: #f4f4f4; padding: 1em;">{message}</div>
TailwindはTailwind Viteプラグインをインストールすればサポートされます。既存のTailwindコードは変更する必要はありません。
Gatsbyではgatsby-browser.js
でCSSインポートを使用してグローバルスタイリングを適用します。Astroでは、主なレイアウトコンポーネントに.css
ファイルを直接インポートしてグローバルスタイリングを適用します。
詳しくはStyling in Astroを参照してください。
画像プラグインを置き換える
セクションタイトル: 画像プラグインを置き換えるGatsbyの<StaticImage />
と<GatsbyImage />
コンポーネントをAstroの独自の画像統合コンポーネントに変換するか、または適切なReactコンポーネントで標準HTMLの<img>
/JSXの<img />
タグへ変換します。
---import { Image } from 'astro:assets';import rocket from '../assets/rocket.png';---<Image src={rocket} alt="A rocketship in space." /><img src={rocket.src} alt="A rocketship in space.">
Astroの<Image />
コンポーネントは.astro
と.mdx
ファイルのみで動作します。完全なコンポーネント属性のリスト (EN)を確認し、いくつかはGatsbyの属性と異なります。
Markdownファイル(.md
)で画像を使用を続ける場合は、標準のMarkdown構文(![]()
)を使用することができます。HTMLの<img>
タグを直接使用することは、ローカル画像の.md
ファイルではサポートされていません。そのため、それをMarkdown構文に変換する必要があります。
# Markdown ページ
<!-- src/assets/stars.png をローカル画像として保存 -->
Reactコンポーネント(.jsx
)で画像を使用する場合は、標準のJSX画像構文(<img />
)を使用することができます。Astroはこれらの画像を最適化しませんが、NPMパッケージをインストールして使用することでより柔軟な選択肢を提供できます。
詳しくはAstroの画像ガイドを参照してください。
Gatsby GraphQLをAstroに変換する
セクションタイトル: Gatsby GraphQLをAstroに変換するGraphQLクエリへの参照をすべて削除し、代わりにローカルファイルのデータにアクセスするにはimport.meta.glob()
を使用してください。
あるいは、コンテンツコレクションを使用している場合は、MarkdownやMDXファイルをgetEntry()
およびgetCollection()
でクエリしてください。
これらのデータリクエストは、Astroコンポーネントのフロントマター内で行われます。
---import { getCollection } from 'astro:content';
// `src/content/blog/` エントリを全て取得するconst allBlogPosts = await getCollection('blog');
// `src/pages/posts/` エントリを全て取得するconst allPosts = Object.values(import.meta.glob('../pages/post/*.md', { eager: true }));---
export const pageQuery = graphql` { allMarkdownRemark(sort: { frontmatter: { date: DESC } }) { nodes { excerpt fields { slug } frontmatter { date(formatString: "MMMM DD, YYYY") title description } } } }`
ガイド付き例:GatsbyレイアウトをAstroへ変換する
セクションタイトル: ガイド付き例:GatsbyレイアウトをAstroへ変換するこの例では、Gatsbyのブログスターターやlayout.js
をsrc/layouts/Layout.astro
に変換します。
ホームページでは1つ目のヘッダーを表示し、それ以外のページでは「Home」へのリンク付きヘッダーを表示します。
-
return()
のJSXを特定するlayout.js import * as React from "react"import { Link } from "gatsby"const Layout = ({ location, title, children }) => {const rootPath = `${__PATH_PREFIX__}/`const isRootPath = location.pathname === rootPathlet headerif (isRootPath) {header = (<h1 className="main-heading"><Link to="/">{title}</Link></h1>)} else {header = (<Link className="header-link-home" to="/">Home</Link>)}return (<div className="global-wrapper" data-is-root-path={isRootPath}><header className="global-header">{header}</header><main>{children}</main><footer>© {new Date().getFullYear()}, Built with{` `}<a href="https://www.gatsbyjs.com">Gatsby</a></footer></div>)}export default Layout -
Layout.astro
を作成して、このreturn
値をAstro構文に変換します。注意点:
{new Date().getFullYear()}
はそのまま動作 🎉{children}
は<slot />
に変換 🦥className
はclass
に変換 📛Gatsby
はAstro
に変換 🚀
src/layouts/Layout.astro ------<div class="global-wrapper" data-is-root-path={isRootPath}><header class="global-header">{header}</header><main><slot /></main><footer>© {new Date().getFullYear()}, Built with{` `}<a href="https://www.astro.build">Astro</a></footer></div> -
レイアウトがHTMLドキュメントに必要な要素を各ページに提供できるように、ページシェルを追加します:
src/layouts/Layout.astro ------<html><head><meta charset="utf-8" /><link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="viewport" content="width=device-width" /><title>Astro</title></head><body><div class="global-wrapper" data-is-root-path={isRootPath}><header class="global-header">{header}</header><main><slot /></main><footer>© {new Date().getFullYear()}, Built with{` `}<a href="https://www.astro.build">Astro</a></footer></div></body></html> -
必要なインポート、props、JavaScriptを追加します
Astroでページルートとタイトルに基づいてヘッダーを条件付きでレンダリングするには:
Astro.props
経由でpropsを提供します。(注:Astroのテンプレートでは、関数に渡すのではなく、フロントマターからpropsにアクセスします)- 三項演算子を使用して、ホームページの場合は1つの見出し、それ以外の場合は別の見出しを表示します
{header}
と{isRootPath}
の変数は不要になったため削除します- Gatsbyの
<Link/>
タグを<a>
アンカータグに置き換えます className
の代わりにclass
を使用します- クラス名を有効にするために、プロジェクトからローカルのスタイルシートをインポートします
src/layouts/Layout.astro ---import '../styles/style.css';const { title, pathname } = Astro.props---<html><head><meta charset="utf-8" /><link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="viewport" content="width=device-width" /><title>Astro</title></head><body><div class="global-wrapper"><header class="global-header">{ pathname === "/"?<h1 class="main-heading"><a href="/">{title}</a></h1>:<h1 class="main-heading"><a class="header-link-home" href="/">Home</a></h1>}</header><main><slot /></main><footer>© {new Date().getFullYear()}, Built with{` `}<a href="https://www.astro.build">Astro</a></footer></div></body></html> -
index.astro
を更新して、この新しいレイアウトを使用して、必要なtitle
とpathname
propsを渡します:src/pages/index.astro ---import Layout from '../layouts/Layout.astro';const pagePathname = Astro.url.pathname---<Layout title="Home Page" pathname={pagePathname}><p>Astro</p></Layout>現在のページのパスは
Astro.url
(EN)で取得できます。 -
条件付きヘッダーをテストするには、同じパターンを使用して2番目のページ、
about.astro
を作成します:src/pages/about.astro ---import Layout from '../layouts/Layout.astro';const pagePathname = Astro.url.pathname---<Layout title="About" pathname={pagePathname}><p>About</p></Layout>Aboutページでは「Home」へのリンクが表示され、ホームページでは表示されません。
コミュニティリソース
セクションタイトル: コミュニティリソース:::注意[共有したいリソースはありますか?] GatsbyサイトをAstroに移行する方法について、参考になる動画やブログ記事を見つけた(または作成した)場合は、このリストに追加してください! :::