X(Twitter) Zenn GitHub RSS 共有

AstroJS

作成日時:2024-07-30
更新日時:2024-08-31

AstroJSを導入した際のメモ。

経緯

新しく技術ブログを作ろうと思ったのでAstroJSを使用した。
以下、選定理由。

環境

導入方法

公式のマニュアルを見ればよい。
日本語対応している。

トラブルシューティングなど

ビルド後に吐き出されたHTMLに改行や空白が入る

astro-compressをインストールする。

Could not load the “sharp” module using the win32-x64 runtime

astro-compressを導入してビルドをしたら、このエラーが出た。
下記サイトを参照して解決。

参考:
sharpの「Could not load the “sharp” module using the win32-x64 runtime」エラーの解決方法 #Sharp - Qiita

目次を追加する

markdownで書いた記事の見出しを一覧で出す。

---
export interface Props {
  headings: { depth: number; slug: string; text: string }[];
}

let { headings } = Astro.props;
const htmlString = [];
headings.map((heading) => {
  htmlString.push(`<li class=depth-${heading.depth}>`);
  htmlString.push(`<a href=#${heading.slug}>${heading.text}</a>`);
  htmlString.push(`</li>`);
});
---

<Fragment set:html={htmlString} />

rehype-slugとrehype-tocをインストールする必要な場合もある。

npm i rehype-slug rehype-toc 

ベースパス

デプロイ先の指定。下記参照。

設定方法 | Docs

コードでの取得方法は下記。

const base = import.meta.env.BASE_URL;

空白行を入れないと改行されない問題

remark-breaksを入れる。下記参照。

Markdownで簡単改行!remark-breaksプラグインの使い方 - ろぼいんブログ

記事一覧の取得方法

await Astro.glob("対象のディレクトリ/*.md")

で下記の情報を配列で取得できる。
frontmatterはmdのfrontmatterの内容が格納されている。

// astro.d.ts
export interface MarkdownInstance<T extends Record<string, any>> {
    frontmatter: T;
    /** Absolute file path (e.g. `/home/user/projects/.../file.md`) */
    file: string;
    /** Browser URL for files under `/src/pages` (e.g. `/en/guides/markdown-content`) */
    url: string | undefined;
    /** Component to render content in `.astro` files. Usage: `<Content />` */
    Content: AstroComponentFactory;
    /** raw Markdown file content, excluding layout HTML and YAML frontmatter */
    rawContent(): string;
    /** Markdown file compiled to HTML, excluding layout HTML */
    compiledContent(): string;
    /** List of headings (h1 -> h6) with associated metadata */
    getHeadings(): MarkdownHeading[];
    default: AstroComponentFactory;
}

下記参照。

Astroチュートリアルメモ その5-1【投稿一覧の取得】

開発中に変数の内容を確認したい

開発サーバーを動かしている状態でconsole.log()を書くと出る。

CSS関連

is:global

コンポーネント内にCSSを設定する場合、is:globalつけないと作用しない可能性もある。

CSSを外部に置く方法

importでcssを取り込んでビルドすると、htmlファイルの中に内容がそのまま書き込まれてしまう。
CSSファイルはpublic直下に置き、head内にlinkタグを書いて取り込めばよし。

CSSのネスト

対応してない可能性。

parent {
    child {

    }
}

上記の形式で書いていたが、ビルド後のcssにchildの定義が存在しなかった。
手動でminifyするかネストをやめるか、それとも他の何かしらを使うか。

Theme

テーマがある。

Themes | Astro

Starlightとかよさげ。

環境変数

環境変数の参照方法は下記。

環境変数 | Docs

import.meta.env.PROD

開発時はfalse、ビルド時はtrueになるらしい。

コンテンツコレクション

ファイル名の先頭にアンスコをつければビルド対象外になる。

コンテンツコレクション | Docs

Google GTMの配置

TypeScriptを使用しているとエラーが出る。
「TypeError: window.dataLayer is not a function」

https://github.com/vercel/next.js/discussions/20784を参照。

Audit

改善点を出してくれる。
開発サーバー起動時に、画面下部に出てくる。

is:inline

scriptタグに付ければTypeScriptのチェックをスキップして、そのまま出力してくれる。

Sitemap

サイトマップの作成方法。

@astrojs/sitemap | Docs

Identifier ‘prevRefreshReg’ has already been declared

既存のReactコンポーネントを導入したら出てきた。
既存のpreactと追加したreactが被ると出るっぽい。
astro.config.mjsからpreactの定義を消したら解決した。

変更内容が反映されない

開発サーバーを再起動すれば大体直る。

RSSの作成

RSSフィードの追加 | Docs

customDataは下記の定義に則って追加する。

ビルドが遅い

画像の圧縮に時間がかかっているせいだった。
たかだが100ページ程度のサイトなのに、ビルドに2分くらいかかった。

そもそも私は画像を別のプログラムで圧縮しているため、astroにやって貰う必要が無い。
astro.config.mjsでcompress()に画像の圧縮を除外する設定を加える。

画像の圧縮の処理を除外したら、5秒で終わった。

export default defineConfig({
  integrations: [compress({ Image: false })],