【フレームワーク】何やら便利そうなのでAstroを触ってみた

静的サイトのコーディングはWebpack+Gulpでビルドして納品していて、EJSで必要に応じてコンポーネントを分けたりしていたんですが、基本的にはHTML直書きとそんなに変わりません。

ただ最近は画像周りのタスク処理が増えてきてビルドに時間がかかるようになったり、またCSSの命名を考えるのも少ししんどいなと思っていたのでコンポーネント単位で解決できるVue.js+Nuxt.jsやReact+Next.jsといったフレームワークで静的サイトジェネレータを活用する方向に切り替えたいなと思っていました。

しかし学習コストが高いように感じることと、そして目前の案件で扱いづらいこともあって進んでいなかったんですが、余裕もできたので最近知ったAstroというフレームワークが良さげなので触ってみることにしました。

色々なフレームワークがサポートされている

Astroは公式のリファレンスにある通り、VueやReactを始めさまざまなフレームワークがサポートされており、柔軟性がありそうなのも良いところです。まずAstroを導入してから、今後プロジェクトに応じてにフレームワークを切替えるなんてこともできそうなところが良いです。

なにより独自の.astro UIという言語がサポートされており、他のフレームワークと比較して一番HTMLに近い形で書けそうなところも触ってみようと思うきっかけになりました。

さっそく開発環境をインストールしてみる

公式の要件によるとNode.jsはv18.14.1以上である必要があります。自分のPCではNode.jsをnvm(Node Version Manager)でインストールしているので切替えて対応しました。またVScode用に公式拡張機能の導入が推奨されていますのでインストールしておきます。

準備が出来たらターミナル上で以下のコマンドでインストールしていきます。

npm create astro@latest

初期設定の入力を質問形式で求められるので順番に入力していきます。
とりあえず下記の通り設定しました。

 astro   Launch sequence initiated.

   dir   Where should we create your new project?
         ./test

  tmpl   How would you like to start your new project?
         ● Include sample files (recommended)
         ○ Use blog template 
         ○ Empty 
      ✔  Include sample files

  deps   Install dependencies?
         ● Yes  ○ No 
      ✔  Yes

    ts   Do you plan to write TypeScript?
         ● Yes  ○ No 
      ✔  Yes

   use   How strict should TypeScript be?
         ● Strict (recommended)
         ○ Strictest 
         ○ Relaxed 
      ✔  Strict

   git   Initialize a new git repository? (optional)
         ● Yes  ○ No 
      ✔  Yes

インストールが完了すると指定したディレクトリ内は以下の構成になりました。

Astroを始めてみる

cdコマンドなどでインストールされたディレクトリに移動したら、さっそく公式ドキュメントにしたがって、npm run devコマンドで開発環境を立ち上げてみます。

npm run dev

> test@0.0.1 dev
> astro dev

  🚀  astro  v3.2.4 started in 71ms
  
  ┃ Local    http://localhost:4321/
  ┃ Network  use --host to expose

上記のコメントが表示されたあとhttp://localhost:4321/というローカルサーバーが立ち上がります。

アクセスすると以下のページがブラウザで表示されました。

構成を見てみる

構成が以下の通りインストールされています。構成については公式にも記載されていますのでざっくり確認してみます。

構成ファイルはsrcディレクトリとpublicディレクトリで格納されます。

  • srcディレクトリ
    • 各コンポーネント、ページ・レイアウトファイル、cssファイルなど。ビルド時にAstroで最適化されます。
  • publicディレクトリ
    • 主に画像やフォントなどのアセットで、Astroによる処理をせずそのまま構成ファイルに含めたい場合はここに格納します。

srcディレクトリにはpages,layouts,componentsに分かれています。

  • pages
    • Webサイトの各ページのルーティングやデータ読み込み、全体的なページレイアウトを処理します。astroファイルの他、markdown(md)やhtmlなどもサポートされるようです。
  • layouts
    • サイト共通のUIコンポーネントを管理。headタグやheader、footerなどが該当します。
  • components
    • 1つ1つ独立したAstroコンポーネントを管理

Astroコンポーネントについて

Astroコンポーネントは主に2つのパートに分かれていて、ハイフン3つ並んだコードフェンスと呼ばれる部分とその外側で分けられています。

コードフェンスに囲まれた部分にはjavaScriptおよびtypeScriptを記述。コードフェンスの外側の部分はHTMLを素のまま記述することでビルド時でもそのまま出力することができます。
このあたりはreactも同じ思想だと思うんですが、reactの場合はclass属性はclassNameで書かないといけなかったりするので、素のままというとちょっと違うんですよね。Astroの場合は本当に素のHTMLでも大丈夫なわけです。なので感覚的にも違和感は少なくて済みそうですね。

ちなみに今回インストールしたテンプレートに含まれていたCardコンポーネントを覗いてみます。

---
interface Props {
	title: string;
	body: string;
	href: string;
}

const { href, title, body } = Astro.props;
---

<li class="link-card">
	<a href={href}>
		<h2>
			{title}
			<span>→</span>
		</h2>
		<p>
			{body}
		</p>
	</a>
</li>
<style>
	.link-card {
		list-style: none;
		display: flex;
		padding: 1px;
		background-color: #23262d;
		background-image: none;
		background-size: 400%;
		border-radius: 7px;
		background-position: 100%;
		transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
		box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
	}
	.link-card > a {
		width: 100%;
		text-decoration: none;
		line-height: 1.4;
		padding: calc(1.5rem - 1px);
		border-radius: 8px;
		color: white;
		background-color: #23262d;
		opacity: 0.8;
	}
	h2 {
		margin: 0;
		font-size: 1.25rem;
		transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
	}
	p {
		margin-top: 0.5rem;
		margin-bottom: 0;
	}
	.link-card:is(:hover, :focus-within) {
		background-position: 0;
		background-image: var(--accent-gradient);
	}
	.link-card:is(:hover, :focus-within) h2 {
		color: rgb(var(--accent-light));
	}
</style>

styleタグの中はコンポーネントに対するスタイルです。これはビルド時に1つのcssにユニークな命名がされた状態で統合される仕組みです。

こうして見ると複雑なことは本当になさそうな印象です。

触ってみた所感

まだ触れた段階で実は何も使いこなしてはいないのですが、概要は理解できた気がします。

公式のドキュメントも基本的な部分は日本語に翻訳されているので、試しみたい方は公式を参照するのが良さそうです。

https://docs.astro.build/ja

その他にも公式のライブラリがあり画像の最適化を図れるastro-imagetoolsなどもよさそうなのでこの辺りのテストも含めて、次はオリジナルのテンプレートを持って形にしてみたいと思います。