Astro 触ってみる
これは Astro 0.x 時代の情報でめちゃ古いです
Next.js で雑に作ったブログを Astro で作り直してみる。
まだドキュメントも読めてなくて、今の認識は「Markdown 読めて React とかも動かせる All-in-One の静的サイトジェネレータ」程度。
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
エラーで進めなかった。
$ 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
examples ディレクトリにそれっぽいのがあったので、手動でコピーしてくる。
$ 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
とりあえず実行してみる
$ 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 にないパッケージを読んでいたりして不思議なのでここから色々追っていく。
さっき読み込まれていた @astrojs/renderer-preact
は 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 のドキュメントを読んだ。
renderer は React や Vue.js などのフレームワークごとに実装されていて、「コンポーネントのビルド時レンダリング」と「イベントハンドラなどのハイドレーション」を責務としているらしい。
このハイドレーションがおもしろい。Astro はデフォルトでは一切の JS を動かさない。ただ、それだとイベントハンドラとか動かないので、Partial Hydration の仕組みを使うことで、JS が必要なコンポーネントだけを読むことができる。
.astro
は JSX ライクな構文。単体でコンポーネントになる。
さっと読んで特徴的なところをあげると
- interface か type を export して Props 定義する
- svelte-way っぽいけど、export で定義するのはあくまで props の型だけで、渡された値を読むのは
Astro.props
という API に分かれているのでそこまで魔法感はない。
- svelte-way っぽいけど、export で定義するのはあくまで props の型だけで、渡された値を読むのは
-
<!-- コメント -->
でかけるの地味にうれしい - JS と HTML を分ける構文がシンプルな Frontmatter で、エコシステムの対応が比較的楽そう
- でも Markdown のほうは普通の Frontmatter なので一貫性なくてあんまり好みではない
VSCode 拡張があった。
syntax highlight と補完は結構いい感じにうごく。
けど Astro
オブジェクトの型情報がなくてちょいきつい。
あ、一応貼っておくと、実際のコードはここにある
CSS Modules が .astro
コンポーネントだと読み込めないので、React コンポーネントとかと併用する場合はスタイルの定義方法が混在することになっちゃうな。コンポーネントはできるだけフレームワーク側に寄せて、Astro コンポーネントをラッパーにするのがはやそうか