先日、ここ1年くらい?ずっと音沙汰がなかったSolidStartに動きがあり。
Release v0.4.0 - Beta 2 · solidjs/solid-start https://github.com/solidjs/solid-start/releases/tag/v0.4.0
何が変わったかなーって見てたら、ほぼ全部書き直して150ファイル10000行から32ファイル1400行になったと。 (もちろん外部ライブラリに逃しただけなので、総量はそんなに変わってないとは思うけど)
一番の変更点として、NitroとVinxiを採用したらしいので、そのあたりどう棲み分けしてるのかをまとめておこうかと。
Nitro
unjs/nitro: Create, build and deploy universal web servers. The open engine powering Nuxt and open to everyone. https://github.com/unjs/nitro
Nuxtのベースになってるやつでもありつつ、他のフレームワークも載せたければ載せられるよっていうやつ。
Nitroそれ自体は、どっちかというとユニバーサルなWebサーバーが書けるフレームワークで、
- ファイルベースのルーティング
- プリレンダリング
- プラグイン機構、ランタイムのHooks
- HMR、Auto import、Tree shaking
- デプロイ先ごとのアダプター
みたいな機能がある。
単体でも使えて、nitro dev
とかnitro build
とかできるし、CLIから何から何までフル実装されてる。(ビルドはrollup
に投げてるけど)
実装はUnJSの総力が結集!みたいな感じになっていて、それぞれすごい読み応えがある。
- HTTPルーター: https://github.com/unjs/h3
- コンフィグ: https://github.com/unjs/c12
- ログ: https://github.com/unjs/consola
await
できるHooks: https://github.com/unjs/hookable- etc…
ほんとにめちゃめちゃいっぱいあるし、全部が粒ぞろいでパワーを感じる。
ちなみに、npm上でnitropack
っていうネームスペースになってるのは、nitro
っていうモジュールが既に存在してるからっぽい。
Vinxi
で、SolidStartは、Nitroを直接使ってるわけではなく、このVinxiっていうレイヤーを介してる。
nksaraf/vinxi: The JavaScript Server SDK https://github.com/nksaraf/vinxi
@nksaraf
氏は、前々からずーっとSolidStartをやってる人。
Vinxiは、NitroとViteをベースにしたフルスタックなサーバー用SDKで、各UIフレームワークとNitroをつなげる自称ルーター、実態はバンドラー相当という感じ。
BunのBun.App
に着想を得て実装されてるとのことで、これはざっくり書くとこういう設定ファイルでアプリがビルドできるぜってアイデア。
// See also https://github.com/oven-sh/bun/pull/2551
[
{
name: "public",
mode: "static",
dir: "./public",
},
{
name: "client",
mode: "build",
handler: "./app/client.tsx",
target: "browser",
plugins: () => [solid({ ssr: true })],
base: "/_build",
},
{
name: "ssr",
mode: "handler",
handler: "./app/server.tsx",
target: "server",
plugins: () => [solid({ ssr: true })],
},
];
各ルートごとのmode
によって、どのURLをどうハンドルするかを自在にできる。
- ただの静的アセット用のルート
- 単なるAPIのルート
- SPAとして動作するルート
- SSRするルート
もしくは、自作したモードも選べて、どんなサイトでもアプリでも作れるぜっていう。
つまり、
- DXとしてViteは使いたい
- もちろん特定のUIフレームワークも動かしたい
- メタフレームワークとして、SSRとかSPAとかあらゆるモードをサポートしたい
- それをどこにでもデプロイしたい
みたいな、昨今のみんなの夢をのせた新進気鋭の実装という感じ。
ほやほやなのでドキュメントサイトが壊れてるのはご愛嬌やけど、このサイトもVinxiでできてる。
Vinxi https://vinxi.vercel.app
コードにあるapp.config.js
を見ると、その雰囲気がわかるはず。
https://github.com/nksaraf/vinxi/blob/12e560d57f4cfc31a81cffd6ea276229d3304577/docs/app.config.js
Vinxi自体はNitroと同じで、特定のフレームワーク向けではない実装でありつつ、RSCみたいな固有な仕組みも載せられるようになってるとのこと。
なので、いま流行りのuse server
も使える・・・!(ただし中身はただのJSONをやり取りできるだけ)
SolidStart
というわけで、そんなNitroとVinxiのさらに上で作られたメタフレームワークがSolidStartというわけ。
solidjs/solid-start: SolidStart, the Solid app framework https://github.com/solidjs/solid-start
(Vinxiのリポジトリにもframeworks/solid-start
ってのがあるけど、これはたぶん古そう)
足回りとしては、
- 設定は
vite.config.js
に書く- Nitroの設定もココで入れられる
- ただし中身はそのままVinxiへ渡る
- CLIは
vinxi dev
とvinxi build
を使う @solidjs/start/config
が、Vinxiの設定をもってる
あと、VinxiのServer functionsを拡張して、JSONだけでなくJavaScript界にあるものなんでも送れるようにしてあったり。
これは@lxsmnsyc
氏のSerovalを使ってるから。氏も昔からSolidをやってる人で、いろんなSolid関連ライブラリを生み出してるお方。
lxsmnsyc/seroval: Stringify JS values https://github.com/lxsmnsyc/seroval
devalue
よりも後発で、対応してるフォーマットが多い・・・!
そのほかには、SolidStart自体がめちゃめちゃ薄くなって、@solidjs/router
と@solidjs/meta
のAPIをre-exportしてたのもなくなった。
- ファイルベースルーティング
- Server functionsとかビルドが絡む機能
- デプロイ先を選ぶアダプター
のように、メタフレームワークという立ち位置でなければできないことだけやるようにしてる、ってスタンス。
たとえばServer actionsも、
@solidjs/router
のactions
を使って、ナビゲーションごとに動かすけど- どこで実行するかは、SolidStartで
use server
してサーバー側でやるようにできる
みたいな合わせ技になる。
それぞれが薄いがゆえに、それを組み合わせる層がユーザーランドに露出してるのが特徴かな〜。 カスタマイズ性は高いけど、どのレイヤーでやるの?ってのを考える必要があったり、その道具を正しく使う必要があったり。
そういう面も含めて、すごくSolidっぽいなって思った。(だからこその知る人ぞ知るポジションなんやろう)
現状コードの全体感を眺めるには、このexamplesが良かった。(experimentsて)
https://github.com/solidjs/solid-start/tree/main/examples/experiments
というわけで
- Nitro+Vinxiによる既存OSSとの調和
- もともとJSXなSolidで、
use server
によるReact方面とのさらなる親和性
このあたりをヨシととるか、引き続き自作路線で一枚岩でいくべきかみたいなのが、メタフレームワーク界隈の関心事って感じなんかね。