Astro触ってみた(Markdownでブログを作ろう)
あけましておめでとうございます。さわちゃんです。
最近個人用の適当なブログを作ろうかなと企んでいて、なにかおもしろいフレームワークがないかな〜と探していたところ、弊社nakaeよりAstroを紹介されました。
試しに書いてみているのですが、静的サイトを作る上での嬉しい機能が盛りだくさんでいい感じのフレームワークだな〜と思っています。
今回の記事では、まずそもそもAstroを知らない方も多いかなと思うので(私自身も最近初めて存在を知りました)、Astroの簡単なご紹介とMarkdownをページとして扱う辺のお話をしていきます。
https://astro.build/
私が印象に残った特徴を公式サイトからいくつか抜粋してご紹介します。
現在人気のオールインワンなJSフレームワーク(Next.jsやNuxt.jsなど)はSPAによる複雑なWebアプリケーションを構築するのに特化している傾向がありますが、SPAは特に初回ロード時の重さがネックでした。
静的サイトはWebアプリケーションのような複雑な操作はそこまで行われないことが多く、また初回ロードはなるべく早い方が好まれる(ブログの記事を開こうとしてロードに時間かかると正直体験は悪いですよね・・・)ので、AstroではMPAを採用しています。
MPAはよくLaravelやRuby on Railsなどサーバー寄りの言語・フレームワークが用いられている印象がありますが、AstroはそれをJSだけで実現したい!という思いがあるみたいですね。
ただ静的サイトといってもヌルヌルと操作したい部分はどうしても出てきてしまうと思いますが、実はAstroでは部分的にCSRを行えます。(詳しくは後ほど)
痒いところに手が届くフレームワークだな〜って印象ですね。
(公式サイトでは「Astroで遅いウェブサイトを構築することは不可能です。」と自信満々な様子)
Astroの中でも特にこの機能に驚いたのですが、Astro内部でReactやVue.js、SvelteやSolidJSなど、別のフレームワーク・ライブラリをコンポーネント単位で部分的に導入できます。
このように、サーバでレンダリングされるHTMLページ(≒海)の一部の動的な部分を独立したアプリ(≒島・コンポーネントに相当)として扱うことを「アイランドアーキテクチャ」と呼ぶみたいです。
(Astroではこのアーキテクチャが元となる「Astroアイランド」と呼ばれるアーキテクチャを導入しています)
静的な部分はサーバ側で処理し、動的な部分のみJSで更新することでパフォーマンスを良くすることができます。
Astroアイランド、上陸したいですよね。
アイランドアーキテクチャ
https://jasonformat.com/islands-architecture/
Astroアイランド
https://docs.astro.build/ja/concepts/islands/
例えば、今回の私の企みである「ブログ」のようなサイトを作るにはうってつけですよね。
なるべくリッチエディタは使いたくないな〜って思っている方も多いと思うので、この機能は嬉しいのではないでしょうか。
ただ、Markdown全体へのスタイルの反映は一工夫必要なので、また後ほど説明します。
npm: v8.13.2
Yarn: v1.22.17
Astro: v1.0
Astroは2022年8月にリリースされたみたいですね(それまではBeta版)
Astroは以下のコマンドでインストールできます。
他のJSフレームワークでもよく見る構成ですね。
publicには画像やフォントなどのアセットが、src以下にはページやコンポーネントなどのソースコードが入ります。
AsrtoではNext.jsやNuxt.jsでおなじみのファイルベースルーティングを採用しているので、ファイルを追加するだけで自動でルーティングの設定も行われます。
今回はsrc > page以下にpostsディレクトリを作成し、その中にpost_1.mdを追加してみましょう。
post_1.md
その場合は以下のような手順で実現できます。
PostLayout.astro
その後、post_1.mdのFront Matter部分に以下を追加してください。
そうすることでこのMarkdownで生成されるページにLayoutを反映させることができます。
ただ、Layoutの子コンポーネントにスタイルを当てる際、少し工夫が必要でした。
まず、AstroではCSSのスコープはそのコンポーネントの中のみとなります。
(レンダリングの際、コンポーネント単位で、コンポーネント内の要素に自動でクラスが割り当てられ、ブラウザで判別するみたいです)
なので、仮にPostLayout.astro内でスタイルを書いたとしても、子コンポーネントにはそのスタイルが適用されません。
そこで、:global()セレクタを用います。
:global()セレクタを使用すると、部分的にグローバルなスコープでのCSSを書けるようになります。
よって、特定のid(今回でいうと”post”)を持つdiv要素などでslot部分を囲み、:global()セレクタと合わせることによって、
「id: postのdivの子要素以下にあるh1に対してcolor: red;を適用する」
みたいなことが実現できます。
(これがベストプラクティスなのか怪しいのでもっと調査します・・・)
今後のテーマとしては
などがあるので、引き続き調査をしていきたいと思います。
とりあえず触ってみた感想ですが、まだパフォーマンスについては実感できていないものの、開発体験としてはファイルベースルーティングを使用しているフレームワークを触っている方であれば、すんなりと書けるかなと思いました。
ほとんど素のHTMLに近い書き味なので、新しく覚えることはそこまでない印象でした。
ちょっとTypeScriptの型の補完が弱いかな〜(設定が悪いだけかもですが)と思うこともありますが、静的サイトを作る上では総合的に見てとてもいい選択肢だなと思います。
みなさんももし静的サイトを作ることがあればAstroの導入を検討してみてもよいのではないでしょうか。
さわちゃんは引き続き個人ブログの作成を頑張っていきたいと思います!
以上です。おつかれさまでした!
最近個人用の適当なブログを作ろうかなと企んでいて、なにかおもしろいフレームワークがないかな〜と探していたところ、弊社nakaeよりAstroを紹介されました。
試しに書いてみているのですが、静的サイトを作る上での嬉しい機能が盛りだくさんでいい感じのフレームワークだな〜と思っています。
今回の記事では、まずそもそもAstroを知らない方も多いかなと思うので(私自身も最近初めて存在を知りました)、Astroの簡単なご紹介とMarkdownをページとして扱う辺のお話をしていきます。
Astroとは
Astroとは、静的サイト構築が得意なオールインワンのJavaScript(以降、JS)フレームワークです。https://astro.build/
私が印象に残った特徴を公式サイトからいくつか抜粋してご紹介します。
MPAのフレームワーク
基本的にMPAのフレームワークです。現在人気のオールインワンなJSフレームワーク(Next.jsやNuxt.jsなど)はSPAによる複雑なWebアプリケーションを構築するのに特化している傾向がありますが、SPAは特に初回ロード時の重さがネックでした。
静的サイトはWebアプリケーションのような複雑な操作はそこまで行われないことが多く、また初回ロードはなるべく早い方が好まれる(ブログの記事を開こうとしてロードに時間かかると正直体験は悪いですよね・・・)ので、AstroではMPAを採用しています。
MPAはよくLaravelやRuby on Railsなどサーバー寄りの言語・フレームワークが用いられている印象がありますが、AstroはそれをJSだけで実現したい!という思いがあるみたいですね。
ただ静的サイトといってもヌルヌルと操作したい部分はどうしても出てきてしまうと思いますが、実はAstroでは部分的にCSRを行えます。(詳しくは後ほど)
痒いところに手が届くフレームワークだな〜って印象ですね。
ハイパフォーマンス
サーバ側でのレンダリングの際、不要なJSを極限まで削ることにより(部分的なCSRを利用しない限りJSゼロになります)、パフォーマンスがとんでもなく優れているようです。(公式サイトでは「Astroで遅いウェブサイトを構築することは不可能です。」と自信満々な様子)
部分的にCSRを行える
静的サイトであっても動的なコンポーネントを使いたいな〜ってことはしばしばありますよね。Astroの中でも特にこの機能に驚いたのですが、Astro内部でReactやVue.js、SvelteやSolidJSなど、別のフレームワーク・ライブラリをコンポーネント単位で部分的に導入できます。
このように、サーバでレンダリングされるHTMLページ(≒海)の一部の動的な部分を独立したアプリ(≒島・コンポーネントに相当)として扱うことを「アイランドアーキテクチャ」と呼ぶみたいです。
(Astroではこのアーキテクチャが元となる「Astroアイランド」と呼ばれるアーキテクチャを導入しています)
静的な部分はサーバ側で処理し、動的な部分のみJSで更新することでパフォーマンスを良くすることができます。
Astroアイランド、上陸したいですよね。
アイランドアーキテクチャ
https://jasonformat.com/islands-architecture/
Astroアイランド
https://docs.astro.build/ja/concepts/islands/
Markdownをページとして扱える
この機能も個人的にはすごいな〜と感動したのですが、Markdownファイル(.md)をそのままページとして使用できます。例えば、今回の私の企みである「ブログ」のようなサイトを作るにはうってつけですよね。
なるべくリッチエディタは使いたくないな〜って思っている方も多いと思うので、この機能は嬉しいのではないでしょうか。
ただ、Markdown全体へのスタイルの反映は一工夫必要なので、また後ほど説明します。
というわけで実際にブログを作ってみた
実際に導入からMarkdownによるページの作成までを行っていきたいと思います。環境
Node.js: v16.12.0~npm: v8.13.2
Yarn: v1.22.17
Astro: v1.0
Astroは2022年8月にリリースされたみたいですね(それまではBeta版)
導入
最近のフレームワークはコマンド一つで導入できるものが多いので嬉しいですね。Astroは以下のコマンドでインストールできます。
# npmの場合
npm create astro@latest
# yarnの場合
yarn create astro
開発環境の起動
# npmの場合
npm run dev
# yarnの場合
yarn run dev
基本的なディレクトリ構成
- public
- src
- page
- その他設定ファイル
他のJSフレームワークでもよく見る構成ですね。
publicには画像やフォントなどのアセットが、src以下にはページやコンポーネントなどのソースコードが入ります。
ページの追加
src > page以下にファイルを追加するだけです。AsrtoではNext.jsやNuxt.jsでおなじみのファイルベースルーティングを採用しているので、ファイルを追加するだけで自動でルーティングの設定も行われます。
今回はsrc > page以下にpostsディレクトリを作成し、その中にpost_1.mdを追加してみましょう。
post_1.md
---
title: 最初の記事です。
author: さわちゃん
description: Astroさいこ〜〜〜
---
# 自己紹介
どうもこんにちは。さわちゃんです。
Markdownページに対するLayoutの反映
Markdownによるページに対し、何かしらのLayoutを反映させたいと思うことは多いのではないでしょうか。(ヘッダーやメニューバー等)その場合は以下のような手順で実現できます。
Layoutファイルの作成
src > layouts以下にPostLayout.astroを作成してください。PostLayout.astro
---
const { frontmatter } = Astro.props;
---
<html>
<h1>{frontmatter.title}</h1>
<div id="post">
<slot />
</div>
<style>
#post :global(h1) {
color: red;
}
</style>
</html>
<slot />は子コンポーネントを入れ込む部分ですね。(Vue.jsなどでおなじみの記法です)その後、post_1.mdのFront Matter部分に以下を追加してください。
layout: ../layouts/PostLayout.astro
そうすることでこのMarkdownで生成されるページにLayoutを反映させることができます。
Markdownページに対するスタイルの反映
Markdownページ内でスタイルを書くこともできますが、だいたい同じ要素に同じスタイルを当てることが多いのではないでしょうか。ただ、Layoutの子コンポーネントにスタイルを当てる際、少し工夫が必要でした。
まず、AstroではCSSのスコープはそのコンポーネントの中のみとなります。
(レンダリングの際、コンポーネント単位で、コンポーネント内の要素に自動でクラスが割り当てられ、ブラウザで判別するみたいです)
なので、仮にPostLayout.astro内でスタイルを書いたとしても、子コンポーネントにはそのスタイルが適用されません。
そこで、:global()セレクタを用います。
:global()セレクタを使用すると、部分的にグローバルなスコープでのCSSを書けるようになります。
よって、特定のid(今回でいうと”post”)を持つdiv要素などでslot部分を囲み、:global()セレクタと合わせることによって、
「id: postのdivの子要素以下にあるh1に対してcolor: red;を適用する」
みたいなことが実現できます。
(これがベストプラクティスなのか怪しいのでもっと調査します・・・)
終わりに
まだまだ書きたいことがたくさんあるのですが、この記事が長くなりすぎてしまうので今回は一旦ここまでとさせていただきます。今後のテーマとしては
- ページネーションの導入(パスパラメータにより現在ページを取得するのでちょっと工夫が必要)
- コンポーネント単位で別フレームワークの導入(仮想DOMなどはどうなる?)
- Next.jsのSSGとの比較(コードの書き方・ビルド結果・パフォーマンスなど)
などがあるので、引き続き調査をしていきたいと思います。
とりあえず触ってみた感想ですが、まだパフォーマンスについては実感できていないものの、開発体験としてはファイルベースルーティングを使用しているフレームワークを触っている方であれば、すんなりと書けるかなと思いました。
ほとんど素のHTMLに近い書き味なので、新しく覚えることはそこまでない印象でした。
ちょっとTypeScriptの型の補完が弱いかな〜(設定が悪いだけかもですが)と思うこともありますが、静的サイトを作る上では総合的に見てとてもいい選択肢だなと思います。
みなさんももし静的サイトを作ることがあればAstroの導入を検討してみてもよいのではないでしょうか。
さわちゃんは引き続き個人ブログの作成を頑張っていきたいと思います!
以上です。おつかれさまでした!