著者の紹介
著者はイナバくん。
某会社でフロントエンドエンジニアをしています。
ガンダムSEEDとコードギアスに再燃中。
この記事で話すこと
今さらながらAstroを触ってみたので、感想を書きます。
ちなみに、イナバくんのフロントエンドエンジニアとしての略歴・技術スタックは以下の通りです。
1. Webサイト制作(WordPress, HTML, CSS, jQuery) + マネジメント
↓
2. 少しHeadless CMSの案件やる(MicroCMS, Nuxt.js)
↓
3. Webアプリケーション開発(Next.js, TypeScript, GraphQL, スクラム開発) ← いまここ
業務ではWebアプリケーションの開発をしているのですが、副業ではサイト制作もしています。
ふと、モダンな技術スタックでサイト制作をするとしたら、何のライブラリ・フレームワークを選定するだろう・・? と思い、Astroに興味を持ちました。
この記事では、イナバくんの目線でAstroの感想を書きます。
AstroはNext.jsの競合ではない
Astroが登場した当初は、GatsbyのようなReactベースのフレームワークだと勘違いしていました。
しかし、Astroは全く異なるフレームワークである事が分かりました。
まず、AstroはReactベースではありません。
HTML, CSS, JSをそのまま書くことができます。
さらに、Vue.jsやReactコンポーネントも利用可能で、JSX記法もサポートされています。
なので、Astroは学習コストが限りなく抑えられたフレームワークであると言えます。
また、AstroはNext.jsと異なり、MPA(Multi Page Application)のフレームワークです。
Next.jsなどのSPAフレームワークの弱点を解決するという思想で開発されたのがAstroです。
SPAの弱点は、初回の読み込みがとても遅いことですが、Astroは初回読み込みがとても速いです。
AstroはMPAであり、さらにbuild時にJSを最小限に減らしているため、ページの読み込み速度を向上させています。
AstroはMPAでJSの排除された静的HTMLなので、静的コンテンツの多いメディアサイトやブログなどが向いています。
逆にNext.jsは、SPAでReactベースなので、インタラクションや機能の多いWebアプリケーションが向いています。
(※ 著者も趣味で1PのサイトをAstro + Vercel で作ってみました: https://ene-ari.vercel.app/)
Next.js と共通している機能
AstroはNext.jsとは異なる思想で設計されているフレームワークですが、共通している機能もあります。
1. モダンな開発環境を提供している
- ホットリロード付きのローカル環境
- 画像の最適化
- TypeScriptがオプションで導入できる
- コンポーネント開発ができる
2. ルーティング機能
/pages
ディレクトリに.astro
ファイルを置くとルーティングできる
3. モジュールバンドル
内部的にViteが使われていて、ビルドが爆速です
Astroの文法について
1. JSXと似ている点
.astro
ファイルでは、HTML・CSS・JSをそのまま書けるので、基本的には特に学習しなくても開発ができます。
また、JSXのように変数・条件分岐・ループができます。
---
const items = ["犬", "猫", "アフリカゾウ"];
const isVisible = true;
---
<ul>
{items.map((item) => (
<li>{item}</li>
))}
</ul>
{isVisible && (<p>出る</p>)}
2. JSX, Next.js と違う点
2.1. イベントハンドラの扱い
JSXと一番の違いは「イベントハンドラの扱い」です。
Next.jsでよく使う下記のようなコードはNGとなります。
---
const handleClick = () => {
console.log("クリックされたお");
}
---
// ❌ NG例 ❌
<button onClick={handleClick}>クリックする</button>
AstroではHTML内のJSがビルド時に排除されるため、JSXのような書き方はサポートされていません。
下記のように<script>
内でDOM操作する必要があります。
<button id="button">クリックする</button>
<script>
const handleClick = () => {
console.log("クリックされたお");
}
document.getElementById("button").addEventListener("click", handleClick);
</script>
複雑なインタラクション(例えばフォームのバリデーションなど)があった場合は、Reactライブラリを使ってインタラクティブなコンポーネントを作って、Astroファイルにimportするのが効率良いと思いました。
ちなみに、このようなインタラクティブなコンポーネントの事を、Astroでは「アイランド」と呼んでいます。
(アイランド = 静的コンテンツの海の中に浮かぶ孤島、らしいです。)
2.2. コンポーネントのPropsの書き方
AstroではNext.jsと違い、コンポーネントファイルの中でtype Props
の型を定義すると、それが自動的にpropsの型になります。
---
type Props = {
title: string;
description?: string;
}
const {title} = Astro.props;
---
<h2>{title}</h2>
{description && <p>{description}</p>}
他にも細かい違いはありますが、詳しくは公式ドキュメントを参照してください。
まとめ
Astroは学習コストがほぼ無い上に、簡単にモダンな開発体験ができます。
また、MPAでかつサーバーファーストで読み込み爆速なので、ブログやポートフォリオサイトやLPなどであれば、Next.jsよりAstro方が最適だと思いました。