Closed8

AstroJS ドキュメント読み込み

まつもとれおなまつもとれおな

Astro を選ぶ理由 [link]

特徴

Astro には以下のような特徴がある。

Astro Islands [link]

一番推し。

<MyReactComponent client:load>

のように、コンポーネントに対して明示的に client:* をマークすることで、対象のコンポーネントのみをインタラクティブにすることができる

クライアントディレクティブは以下の種類がある

  • client:load
  • client:idle
  • client:visible
  • client:visible={{rootMargin}}
  • client:media={{string}}
  • client:only={{string}}
  • カスタムで作成

利点

  1. JavaScript はバイト単位で読み込むことができるリソースの中で最も遅いものの一つであるため、1バイトでも減らすのが重要。そのため、必要な箇所のみに JavaScript を有効にするとパフォーマンスが向上する
  2. 複数の Astro Islands があると、それぞれが独立してハイドレーションされる。そのため、ページ上部にヘッダーが、ページ下部に重いカルーセルがある場合でも、カルーセルを待つことなくヘッダーがインタラクティブな状態となる。
  3. レンダリング方法とタイミングをクライアントディレクティブで制御することが可能。
まつもとれおなまつもとれおな

クライアントディレクティブについて [link]

client:load

  • ページロード時、即座にコンポーネント JavaScript をロードし、ハイドレートする
  • すぐに目に入る UI 要素で、できるだけ早くインタラクティブにする必要があるもの

client:idle

client:visible

  • コンポーネントがユーザーのビューポートに入ると、コンポーネント JavaScript をロードしてハイドレートする
  • 内部的には IntersectionObserver を利用して追跡しているらしい
  • 優先度の低い UI 要素で、ページ下部や折りたたみ部分の下など、読み込むためにリソースを利用しなければユーザーがその要素を目にしない場合などに利用される

client:visible={{rootMargin}}

  • astro@4.1.0 にて追加された内容
  • コンポーネント自体ではなく、コンポーネントの周りの指定されたマージンがビューポートに入った時にハイドレートする

client:media={{string}}

  • 特定のメディアクエリが満たされると、コンポーネントの JavaScript をロードし、ハイドレートする
  • サイドバーのトグルや、特定の画面サイズでのみ表示される場合などに利用できる

client:only={{string}}

  • HTML サーバレンダリングをスキップし、クライアント上でのみレンダリングを行う
  • client:load と同様、ページロード時に即座にコンポーネントをロード・レンダリング・ハイドレートする
  • Astro はビルド中やサーバ上でコンポーネントを実行しないため、正しいフレームワークを値として渡す必要がある

カスタム

  • 自身が作成することも可能らしい
まつもとれおなまつもとれおな

チュートリアル [link]

ブログを作る

  • Astro の思想と実装方法を知ることができる
  • コンポーネント・レイアウト・スクリプトファイルの作成方法を実践的に知ることができる
  • Astro.props, Astro.params, Astro.glob() などの利用方法を知ることができる
  • Astro Islands の使い方を知ることができる

ブログの完成イメージ

まつもとれおなまつもとれおな

ディレクトリ構成 [link]

ディレクトリとファイルのルール

すべてのAstroプロジェクトのルートには、以下のディレクトリとファイルを含む必要がある。

  • src/* - プロジェクトソースコード(コンポーネント、ページ、スタイルなど)
  • public/* - コード以外の処理不要のアセット(フォント、アイコンなど)
  • package.json - プロジェクトマニフェスト
  • astro.config.mjs - Astroの設定ファイル(推奨)
  • tsconfig.json - TypeScriptの設定ファイル(推奨)

推奨と記載されているものも作成する前提で良いと思う。

一般的にはこのような構成で作成されるらしい。

テストの実装は src/tests などに入れた方が良さそう。

まつもとれおなまつもとれおな

コンポーネント [link]

コンポーネント構造

Astro には

  1. コンポーネントスクリプト
  2. コンポーネントテンプレート

の 2 つの構造に分かれて実装される。

---
// コンポーネントスクリプト (JavaScript)
---
<!-- コンポーネントテンプレート (HTML + JS Expressions) -->

コンポーネントスクリプト

コードフェンス (---) の中に記載される。
この中ではテンプレートをレンダリングするために必要な JavaScript を記載できる。

  • 他の Astro コンポーネントの import
  • 他のフレームワークコンポーネント (React など) の import
  • データ (JSON など) の import
  • API や DB からコンテンツを取得するためのコード
  • テンプレート側で参照する変数の作成

コンポーネントテンプレート

コードフェンス (---) の下に記載される。
プレーンな HTML を実装すれば、対象のコンポーネントを利用する際にその HTML をレンダリングする。

Astro のコンポーネントテンプレート構文 (後で細かく記載) は

  1. JavaScript の式
  2. Astro の <style>, <script> タグ
  3. import したコンポーネント
  4. Astro ディレクティブ (後で細かく記載)

を利用することで、動的に作成された HTML を作成することができる。

props の渡し方

コンポーネントスクリプト側に Astro.props を定義することで props の受け渡しを実装することができる。

---
const { greeting, name } = Astro.props;
---
<h2>{greeting}、{name}!</h2>

コンポーネントをインポートして、他の Astro コンポーネント・レイアウト・ページで利用する際は以下のように props を渡す

---
import GreetingHeadline from './GreetingHeadline.astro';
const name = 'Astro';
---
<h1>グリーティングカード</h1>
<GreetingHeadline greeting="やぁ" name={name} />
<p>素敵な一日をお過ごしください!</p>

Typescript の props 型のインターフェースで props を定義するには interface を利用すれば良い。

---
interface Props {
  name: string;
  greeting?: string;
}

const { greeting = "こんにちは", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

スロット

<slot /> 要素をコンポーネント内に配置することで、コンポーネントの子要素 (children) を実装することが可能。

<slot name="after-header" /> のように、name を定義することで、各箇所に子要素を渡すことが可能。
コンポーネントを利用する側は
<p ==slot="after-footer"==>Copyright 2022</p> などを定義していただければ利用できる。

フォールバックコンテンツ

<slot> タグで囲うことで、タグ内のアイテムをフォールバックコンテンツとして利用することが可能

まつもとれおなまつもとれおな

ページ [link]

基本的にはチュートリアルを読めばわかる。

サポート対象ファイル

  • .astro
  • .md
  • .mdx (MDXインテグレーションがインストールされている場合)
  • .html
  • [.js/.ts] (エンドポイントとして)
まつもとれおなまつもとれおな

レイアウト [link]

共通の UI を提供する Astro コンポーネントは レイアウト と呼ばれる。
Astro のレイアウトコンポーネントは基本的に以下を提供する。

  • ページシェル
    • <html>
    • <head>
    • <body>
  • ここのページコンテンツが挿入される場所を指定する <slot />

一般的には src/layouts に格納されるが、レイアウト名の先頭に_をつけることで、ページと同じ箇所に配置することも可能。

レイアウトコンポーネントの中にレイアウトコンポーネントを含めても大丈夫。

まつもとれおなまつもとれおな

Astro テンプレートの構文 [link]

JSX のような式

Astro コンポーネントのフロントマターのコードフェンス (---) の間に、JavaScript のローカル変数を定義できる。
変数の注入は JSX の実装のような式を利用して代入することができる。

変数

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

動的属性

ローカル変数を波括弧で囲うことで、HTML 要素とコンポーネントの両方に属性渡すことが可能。
テンプレートリテラルも対応

---
const name = "Astro";
---
<h1 class={name}>属性を式で指定できます</h1>

<MyComponent templateLiteralNameAttribute={`私の名前は${name}です`} />

動的 HTML (条件付きレンダー)

React と同様、条件付きレンダリングも可能

---
const visible = true;
---
{visible && <p>表示!</p>}

{visible ? <p>表示!</p> : <p>あるいはこちらを表示!</p>}

動的タグ

変数として HTML タグ名やインポートされたコンポーネントを設定することで、動的タグも利用することが可能。

---
import MyComponent from "./MyComponent.astro";
const Element = "div";
const Component = MyComponent;;
---
<Element>Hello!</Element>
<Component />

フラグメント

<Flagment> </Flagment> もしくは <> </> を利用することができる。
set:* ディレクティブを使用する際、ラッパー要素を避けるために役立つ。

---
const htmlString = '<p>生の HTML コンテンツ</p>'
---
<Fragment set:html={htmlString} />

Astro と JSX の違い

いくつかある。

属性

JSX では camelCase 形式が利用されるが、Astro では kebab-case 形式を利用する。
class でも className ではなく class を利用する。

複数の要素

Astro コンポーネントテンプレートは複数の要素をレンダリングすることができる。
そのため、JavaScript や JSX のように、全体を <div> 要素や <> で囲う必要はない。

コメント

Astro では HTML 形式のコメントと JavaScript 形式のコメントを双方とも使用することができる。

このスクラップは2日前にクローズされました