articles 【Astrobit】MoonBitでAstroのコンポーネントを書いてみた
【Astrobit】MoonBitでAstroのコンポーネントを書いてみた
Astroにはisland機能でReactやSvelteなどで書いたcomponentが使用できるように公式でインテグレーションが用意されているのですが、その他のUIフレームワークでもcomponentを書くためにカスタムインテグレーションが作成できるようになっています。
そこで、moonbitのコードでastroのcomponentを記述するUIフレームワークAstrobitを作成しました。リアクティブな動作はmizchiさんの signals を用いています。これによりsolid.jsのようなsignalベースのDOM更新が可能になっています。
-
パッケージ: https://mooncakes.io/docs/SouichiroTsujimoto/astrobit
-
実際に使用したサンプルページ: https://astrobit-sample.vercel.app/
使い方(例)
具体的にはastrobit-sampleのリポジトリのREADMEや、astrobit本体を参照してください。
環境構築は(結構簡単にできるようになっているつもりなので)省略して、コア部分を紹介します
src/components/counter.mbtなどに以下のようにコンポーネントを書きます
fn counter(props : @dom.Props) -> @a.Node {
let initial = props.get_int("initial")
let count = @signals.signal(initial)
@a.div(attrs={ "class": "counter-widget" }, [
@a.div(attrs={ "class": "counter-display" }, [
@a.span(
attrs={ "class": "counter-value" },
@a.dyn_text(fn() { count.get().to_string() }),
),
]),
@a.div(attrs={ "class": "counter-controls" }, [
@a.button(attrs={ "class": "counter-btn btn-dec" }, "−")
|> @a.on_click(fn(_) { count.update(fn(n) { n - 1 }) }),
@a.button(attrs={ "class": "counter-btn btn-reset" }, "Reset")
|> @a.on_click(fn(_) { count.set(initial) }),
@a.button(attrs={ "class": "counter-btn btn-inc" }, "+")
|> @a.on_click(fn(_) { count.update(fn(n) { n + 1 }) }),
]),
])
}
///|
pub fn mount(element : @dom.Element, props : @dom.Props) -> Unit {
@a.mount_dom(element, counter(props))
}
///|
pub fn render(props : @dom.Props) -> String {
@a.render_to_html(counter(props))
}
///|
pub fn hydrate(element : @dom.Element, props : @dom.Props) -> Unit {
@a.hydrate_dom(element, counter(props))
}
あとはsrc/components/Welcome.astroなどのファイルから
import Counter from './counter/counter.mbt'
// ...
<Counter client:load initial={0} />
このように書くだけで使用できます
ディレクトリ構造はこんな感じです
src/
├── assets
│ ├── astro.svg
│ └── background.svg
├── components
│ ├── Welcome.astro
│ ├── codeSnippets.ts
│ ├── counter
│ │ ├── counter.mbt
│ │ └── moon.pkg
│ └── todos
│ ├── moon.pkg
│ └── todos.mbt
├── layouts
│ └── Layout.astro
└── pages
Moonbitもっと使いたい
個人的にはwasm-gcをターゲットとしたビルドに惹かれてMoonbitを触ってみたので、wasmを使用した面白い例も書いてみたいです。Astrobitの前に、spin frameworkを使用したwasmで動作するAPIサーバをClaudeに書かせたりしたのですが、こちらももう少しちゃんと公開する価値のあるものになれば公開したいです。
最後までお読みいただき、ありがとうございます