Astroを初めて触ってみて良かったポイント

## はじめに
先日[Astro](https://astro.build/)を使ってLPを作りました。初めて使ってみた所感を簡単にまとめてみます。

## Astro is 何
AstroはReactやNext.js感覚で作ったページのHTMLファイルを出力してくれるフレームワークです！

...かなり主観的かつ雑な説明になってしまいました。
公式では「**コンテンツ重視**のWebサイトを**高速に**構築するためのWebフレームワーク」であると説明されています。

>Astro is an all-in-one web framework for building fast, content-focused websites.

https://astro.build/

設計原則として下記の5点が挙げられています。

- Content-focused
- Server-first
- Fast by default
- Easy to use
- Fully-featured, but flexible

https://docs.astro.build/en/concepts/why-astro/

### 「コンテンツ重視」なのがポイント
大きな特徴としては、1番目の原則に"Content-focused"と表現されているように、**コンテンツを重視**して設計されている点と言えるかと思います。

最近流行りのSPAフレームワークはWebサイトではなく、より複雑な**Webアプリケーション**を作るために設計されています。
静的な、あるいは動的な要素が少ないページをこれらのフレームワークで作るには高機能すぎるわけです。

実際、Next.jsで開発しているアプリのLPを同じNext.jsプロジェクト内で作成したのですが、**LPはほぼ静的なページにも関わらず、パフォーマンスのスコアがあまり良くない**ということがありました。ビルドされるJavaScriptを読み込む影響で、ある程度仕方ないのかな〜という感じです。

AstroはビルドするとシンプルなHTMLとアセットのファイルを生成してくれるのです！

なのでJavaScriptも必要最小限、使わなければNo JavaScriptでいけるわけです！

## SEOにもいいぞ
LPのようなページは**SEO**が重要になってくるかと思います。

Googleが検索ランキングに**Webページのユーザーエクスペリエンスをより重視する**方針を発表し、2021年にはその指標に**Core Web Vitals**というものが加えられました。

https://web.dev/vitals/?hl=ja#core-web-vitals

https://developers.google.com/search/docs/appearance/core-web-vitals?hl=ja

そのため現在は、SEO評価をあげるにはCore Web Vitalsの指標スコアを意識することが重要なわけです。

そういう点でも、シンプルに速いページを作れるのは嬉しいですね！

## うれしいポイント
静的ファイルが欲しいならシンプルにHTMLとCSS（必要があればJSも）で書けばいいじゃんというのもありますが、Astroを使ってみて良かったです。

初めて触ってみて感じたうれしいポイントを挙げてみます。

- ReactやNext.jsと同じような感覚で書ける
- sassの導入が楽
- 画像最適化ができる（※パッケージを使う必要あり）



### ReactやNext.jsと同じような感覚で書ける
React/Next.jsでの開発に慣れ親しんできた私にはこれはうれしいポイントでした。

ReactやNext.jsに慣れている人は学習コストをほとんどかけずに直感的に触り始められるのではないでしょうか？

ディレクトリの構成や、ファイルベースルーティングを採用している点はほぼNext.js感覚です。

- コンポーネントやページのファイルは`src/`ディレクトリ
    - ページは`src/pages/`ディレクトリ
    - ページテンプレートのようなLayoutコンポーネント
- アイコンや画像などのアセットは`public/`ディレクトリ

https://docs.astro.build/ja/core-concepts/project-structure/

#### コンポーネント指向
これだけでも使うモチベーションはだいぶ高まりますね。笑

一つのファイルにズラズラーっとHTMLを書いたり、CSS用のクラス名を考えたり..というのは長らくReactでの開発に慣れていた自分にはもはや苦行のイメージしかありません。

コンポーネントを組み合わせてページを作ることができるので、例えばLPならキービジュアル、概要、利用シーン、よくある質問、といった感じでセクションごとにコンポーネントを切ることでだいぶ見通しが良くなります！

#### .astroファイルの例
ファイルの拡張子こそ.astroですが、HTML部分をJSXライクに書けます。

また変数だけでなく、prposを使うこともできます！
その場合は上部の2つの`---` で囲まれたエリアで定義します。
別のコンポーネントやパッケージで用意されているものをimportする際もここに書きます。

```.astro
---
// importしたり、変数やpropsを定義する記述をここに書く

const name = "Astro";
---

<div>
  <h1>Hello {name}!</h1>
</div>
```

このコードの場合、HTMLとして出力される内容は

```
<div>
    <h1>Hello Astro!</h1>
</div>
```
になります。

（Qiita記事では.astroコードのハイライト対応してない模様ですね）

#### スコープ化される
また、コンポーネントは基本的に**スコープ化**されているので、CSS用のクラス名に頭を悩ませるなんてこともなくなります！

```.astro
---
const name = "Astro";
---
<div>
  <h1>Hello {name}!</h1>
</div>

<style>
  h1 { color: red; }
</style>
```

上のコードの場合、次のようにHTML出力/コンパイルされます。

```.html
<div class="astro-HOGE">
    <h1>Hello Astro!</h1>
    <p class="text">This is Qiita</p>
</div>
```

```.css
h1:where(.astro-HHNQFKH6) {
  color: red;
}
.text:where(.astro-HHNQFKH6) {
  color: blue;
}
```

このように`.astro-HOGE`といった感じでランダムな一意のクラス名が付与されます。

なので、別々のコンポーネントファイルで同じクラス名をつけていたり、`<style>`タグの中でセレクタ指定をしていてもCSSがバッティングすることがないです。

#### おまけ
VSCodeを使っている場合は拡張機能の`Astro`を入れると.astroファイルにもハイライトが効くようになります！

https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode

### Sass（SCSSの）導入がめちゃ楽
Astroはビルドツールに[Vite](https://ja.vitejs.dev/)を使っていて、Vite経由でSass（SCSS）を使えます。

- sassのパッケージを追加 `yarn add -D sass`
- .astroファイルのstyleタグに`lang=scss`を追記

これだけでSCSSを使えるようになりました！

webpackとかだと設定にもう少し面倒な印象があったので、とても感動。

```.astro
---
const name = "Astro";
---
<div>
  <h1>Hello {name}!</h1>
</div>

<style lang="scss"> // これを追記
</style>
```

#### mixinを使えるようにするのも楽
css変数や関数も使いたいですよね？

Astroの設定をするファイル`astro.config.mjs`に以下のように書けばOKです。

これであらゆるコンポーネントから定義した変数や関数を呼び出せるようになります！

```astro.config.mjs
export default defineConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          // importしたいファイルを記載 
          additionalData: `@import "src/styles/_mixin.scss", "src/styles/rem.scss";`
        }
      }
    }
  }
});
```

ちなみにSassのmixinを使わずとも`define:vars`ディレクティブを用いることでcss変数使うこともできるようです。
ただ記述がちょっとめんどくさそうだったのとcss変数系は1箇所に集約しておいた方が見やすそうという理由から、自分は使いませんでした。

https://docs.astro.build/ja/reference/directives-reference/#definevars

### 画像最適化ができる
:::note warn
補足
Astroの画像最適化には[@astrojs/image](https://docs.astro.build/ja/guides/integrations-guide/image/#why-astrojsimage)を使うことでも対応できますが、ここではastro-imagetoolsの方を紹介します。
:::

[astro-imagetools](https://astro-imagetools-docs.vercel.app/en/introduction)のパッケージを使えば画像の最適化をすることができるので、画像が多くなりがちなLPやWebサイトのパフォーマンス向上をサポートしてくれます！

https://astro-imagetools-docs.vercel.app/en/introduction

導入も簡単で、astro-imagetoolsをインストールして`astro.config.mjs`に下記の記述をすればOK！

```astro.config.mjs
import { defineConfig } from 'astro/config';
import { astroImageTools } from "astro-imagetools";

export default {
  integrations: [astroImageTools],
};
```

実際の使い方や出力結果については、こちらの記事が例もしっかり載せてくれているので参考になるかと思います。

https://qiita.com/heeroo_ymsw/items/07a4dbeac9515559694f

https://zenn.dev/kalubi/articles/fe704a8305e9b9

Next.jsの[Imageコンポーネント](https://nextjs.org/docs/pages/api-reference/components/image)に近い印象ですね！

#### 背景画像の最適化もできちゃう
特にすごいなと思ったのは背景画像の最適化もできる点です。

LPとかだとキービジュアルの背景にバーンと写真を置くこともよくあると思います。
そういった画像はだいたい画像サイズも大きくなりがちなので、最適化してくれるのはすごくいいですよね！

使い方は通常の画像（ImageやPictureコンポーネント）とほぼ同じです（詳細は割愛）。

https://astro-imagetools-docs.vercel.app/en/components/BackgroundImage

https://astro-imagetools-docs.vercel.app/en/components/BackgroundPicture

---

という感じで、画像が多いページでもいい感じに軽くしてくれそうです。

## おわりに
Astroを初めて使ってみた所感をサクッとまとめてみました。

今回触ってみたのはほんの一部ですが、今後同じような場面があればまたAstroを使いたいなと思うくらいには恩恵を感じられています！

ドキュメント見る限り、環境変数を使ったりクライアント側で制御したりと複雑な設定もできるようなので、また色々試してみたいと思います！

## 参考
- [Astro公式ドキュメント](https://astro.build/)
- [astro-imagetools公式ドキュメント](https://astro-imagetools-docs.vercel.app/en/introduction)
- [Astroの画像インテグレーションAstro ImageToolsを使うときに注意すること](https://qiita.com/heeroo_ymsw/items/07a4dbeac9515559694f)
- [初めてのAstroで画像最適化を試してみた @astrojs/imageとastro-imagetools](https://zenn.dev/kalubi/articles/fe704a8305e9b9#astro-imagetools)