Closed11

Astro 触ってみる

Yuku KotaniYuku Kotani

Next.js で雑に作ったブログを Astro で作り直してみる。
まだドキュメントも読めてなくて、今の認識は「Markdown 読めて React とかも動かせる All-in-One の静的サイトジェネレータ」程度。

Yuku KotaniYuku Kotani

README 見て init してみる。よくわからんけど、ブログ作りたいのでブログを選ぶ

$ npm init astro
npx: 11個のパッケージを1.531秒でインストールしました。

Welcome to Astro! (create-astro v0.5.0)
If you encounter a problem, visit https://github.com/snowpackjs/astro/issues to search or file a new issue.

> Prepare for liftoff.
> Gathering mission details...
? Which app template would you like to use? › - Use arrow-keys. Return to submit.
    Starter Kit (Generic)
❯   Blog
    Documentation
    Portfolio


Yuku KotaniYuku Kotani

エラーで進めなかった。

$ npm init astro
npx: 11個のパッケージを1.531秒でインストールしました。

Welcome to Astro! (create-astro v0.5.0)
If you encounter a problem, visit https://github.com/snowpackjs/astro/issues to search or file a new issue.

> Prepare for liftoff.
> Gathering mission details...
✔ Which app template would you like to use? › Blog
✔ Using template's default renderers › Preact
> Copying project files...
zlib: unexpected end of file

Blog 以外を選んでも同じ。ちょうど 21h 前に報告されていた。snowpack/astro#655

Yuku KotaniYuku Kotani

examples ディレクトリにそれっぽいのがあったので、手動でコピーしてくる。
https://github.com/snowpackjs/astro/tree/main/examples/blog

$ git clone https://github.com/snowpackjs/astro
Cloning into 'astro'...
remote: Enumerating objects: 12873, done.
remote: Counting objects: 100% (1960/1960), done.
remote: Compressing objects: 100% (726/726), done.
remote: Total 12873 (delta 1240), reused 1846 (delta 1186), pack-reused 10913
Receiving objects: 100% (12873/12873), 55.20 MiB | 706.00 KiB/s, done.
Resolving deltas: 100% (7911/7911), done.
$ mv astro/examples/blog/* ./
$ rm -R astro
Yuku KotaniYuku Kotani

とりあえず実行してみる

$ npm i
$ npm run start
> yuku.dev@0.0.1 start /Users/yukukotani/ghq/github.com/Monchi/yuku.dev
> astro dev

[20:57:52] [snowpack] Hint: run "snowpack init" to create a project config file. Using defaults...
[20:57:52] [snowpack] Welcome to Snowpack! Because this is your first time running
this project, Snowpack needs to prepare your dependencies. This is a one-time step
and the results will be cached for the lifetime of your project. Please wait...
[20:57:52] [snowpack] + astro/dist/internal/__astro_component.js@0.17.1
[20:57:52] [snowpack] └── shorthash@0.0.2 (dedupe)
[20:57:53] [snowpack] └── estree-util-value-to-estree@1.2.0 (dedupe)
[20:57:53] [snowpack]   └── is-plain-obj@3.0.0
[20:57:53] [snowpack] └── astring@1.7.5 (dedupe)
[20:57:53] [snowpack] + astro/dist/internal/element-registry.js@0.17.1
[20:57:53] [snowpack] + @astrojs/renderer-preact/server@0.1.3
[20:57:53] [snowpack] └── preact@10.5.14 (dedupe)
[20:57:53] [snowpack] └── preact-render-to-string@5.1.19 (dedupe)
[20:57:53] [snowpack]   └── preact@10.5.14 (dedupe)
[20:57:53] [snowpack] + @astrojs/renderer-preact/client@0.1.3
[20:57:54] [snowpack] └── preact@10.5.14 (dedupe)
[20:57:54] [snowpack] + astro/dist/internal/h.js@0.17.1
[20:57:54] [snowpack] + astro/components/Prism.astro@0.17.1
[20:57:54] [snowpack] └── @astrojs/prism@0.2.2
[20:57:54] [snowpack] └── prismjs@1.24.1
[20:57:54] [snowpack] + astro/components@0.17.1
[20:57:55] [snowpack] └── @astrojs/prism@0.2.2 (dedupe)
[20:57:55] [snowpack] └── prismjs@1.24.1 (dedupe)
[20:57:55] [snowpack] Ready!
[dev server] Server started in 3134ms.
[dev server] Local: http://127.0.0.1:3000/
[20:57:55] [snowpack] watching for file changes...
[access] /
[access] /_astro/src/components/BlogPostPreview.astro.css
[access] /_astro/src/components/BlogHeader.astro.css
[access] /_astro/src/components/BlogPost.astro.css
[access] /_astro/src/components/Author.astro.css
[access] /_snowpack/hmr-client.js
[access] /blog.css
[access] /favicon.svg

うごいた風。
Astro の内部にいるであろう Snowpack が package.json にないパッケージを読んでいたりして不思議なのでここから色々追っていく。

Yuku KotaniYuku Kotani

さっき読み込まれていた @astrojs/renderer-preactastro.config.mjs で指定されていた。

astro.config.mjs
export default {
  // projectRoot: '.',     // Where to resolve all URLs relative to. Useful if you have a monorepo project.
  // pages: './src/pages', // Path to Astro components, pages, and data
  // dist: './dist',       // When running `astro build`, path to final static output
  // public: './public',   // A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don’t need processing.
  buildOptions: {
    // site: 'http://example.com',           // Your public domain, e.g.: https://my-site.dev/. Used to generate sitemaps and canonical URLs.
    sitemap: true,         // Generate sitemap (set to "false" to disable)
  },
  devOptions: {
    // port: 3000,         // The port to run the dev server on.
    // tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
  },
  renderers: [
    '@astrojs/renderer-preact'
  ]
};

renderer のドキュメントを読んだ。
https://github.com/snowpackjs/astro/blob/main/docs/core-concepts/ui-renderers.md

renderer は React や Vue.js などのフレームワークごとに実装されていて、「コンポーネントのビルド時レンダリング」と「イベントハンドラなどのハイドレーション」を責務としているらしい。

このハイドレーションがおもしろい。Astro はデフォルトでは一切の JS を動かさない。ただ、それだとイベントハンドラとか動かないので、Partial Hydration の仕組みを使うことで、JS が必要なコンポーネントだけを読むことができる。

Yuku KotaniYuku Kotani

.astro は JSX ライクな構文。単体でコンポーネントになる。

https://github.com/snowpackjs/astro/blob/main/docs/core-concepts/astro-components.md

さっと読んで特徴的なところをあげると

  • interface か type を export して Props 定義する
    • svelte-way っぽいけど、export で定義するのはあくまで props の型だけで、渡された値を読むのは Astro.props という API に分かれているのでそこまで魔法感はない。
  • <!-- コメント --> でかけるの地味にうれしい
  • JS と HTML を分ける構文がシンプルな Frontmatter で、エコシステムの対応が比較的楽そう
    • でも Markdown のほうは普通の Frontmatter なので一貫性なくてあんまり好みではない
Yuku KotaniYuku Kotani

CSS Modules が .astro コンポーネントだと読み込めないので、React コンポーネントとかと併用する場合はスタイルの定義方法が混在することになっちゃうな。コンポーネントはできるだけフレームワーク側に寄せて、Astro コンポーネントをラッパーにするのがはやそうか

このスクラップは2021/12/09にクローズされました