Ladle 調べてみる
※ 以下の Zenn の記事を見た方が手っ取り Ladle を体験できるので、そちらを見るのを推奨。
Storybook の置き換え候補として開発された[1] Ladle というツールを調べて触ってみる。
Storybook のコンセプトや機能を愛するユーザー(Uber)が、より良い Storybook を作ったといったところ。
-
Ladle has been developed as a drop-in replacement of Storybook - https://www.ladle.dev/blog/introducing-ladle ↩︎
ほとんどは公式ドキュメントのまとめや訳になりそう。
絵文字やアイコンの通り、 ladle = お玉・ひしゃく なので、発音は léidl レイドル っぽい。
0.10.2 で React 18 に対応した模様。引き続き 17 以下でも使える。
まだ Windows では config ファイルをうまく読み込めない模様…
1.0.0 に到達した
Windows でも動くようになったらしい?
Vite 3 に対応したメジャーバージョンアップ。Ladle そのものに breaking changes があったわけではないらしい。
Storybook の課題
Ladle ではどう変わったか・解決されたかを確認する。
Ladle で提示されていた課題
この記事を見る限り、パフォーマンス向上が主眼のように見える。
- ビルド時間の長さ
- 開発サーバーの起動時間の長さ
- 開くときの読み込み時間の長さ(TTI の遅さ)
- 設定や依存のメンテナンスのしにくさ
- 他のツールからの利用しにくさ
(スクラップ筆者が感じていた課題)
Storybook を運用する上での個人的な懸念は、既出のものを除くと以下の点だった。(昔のことなので最近は大丈夫かもしれない。今なら信頼できるか、という点でまだ議論の余地は残るかもしれないが。)
- 長期運用(年単位)するにはツールが不安定すぎる
- 体感的に Breaking Changes が多く、Storybook のバージョンアップで Story の大改修が必要になるか壊れる。
- Storybook のコードが特定のライブラリに強く依存しており、製品コードと独立にバージョンアップできない。
- 未確認だが emotion とか react-router とか webpack とか
- alpha 版含む最新バージョンでのみバグ修正されるため、(安定版が出るまでの間)しばらくバグが直らない。
- alpha 版はもちろん不安定なので使うのは厳しい
- 過去バージョン複数は大変なのでそれらへのバックポートは無くて良いのだが、せめて最新安定版に適応してくれれば…
- 使い勝手
- 意図せずショートカットを実行してしまったりする
- 製品コード用の Webpack 設定そのままでは Storybook のコンテンツが期待通り動かなかったりする
Ladle の機能 - 高速さ
ES modules コード(実態はTypeScript)、かつ、Vite を使うことで[1]、起動時間を大幅に短縮した。(なお、Storybook も Vite が使える[2]はずだが言及されていない。)
速度比較(※上記の記事より引用)
Storybook | Ladle | 比較 | |
---|---|---|---|
Cold start | 58s | 6s | 10% |
Hot start | 25s | 3s | 12% |
Production ビルド | 80s | 22s | 28% |
hot reload | 2.5s | <100ms | <4% |
総ビルドサイズ | 16.1MB | 4.6MB | 29% |
初期ダウンロードサイズ | 338kB | 14.3MB | 2% |
Vite と Code Splitting の恩恵をよく受けるよう作られているように感じる。
-
デプロイ用ビルド時には Rollup で最適化するらしい - https://www.ladle.dev/docs/ ↩︎
Ladle の機能 - 使い勝手の良さ
Storybook 互換
- Ladle は Component Story Format に準拠しているため Storybook の Story をそのまま表示できる。
- Storybook の Controls も同じような機能があるらしい?
準備
- 初期状態からいろいろな機能・アドインが載っている
- 設定ファイルいらず("Zero Configuration")
他のツールとの繋ぎやすさ
- アドインの状態が URL に含まれるため再現しやすい
- Story 一覧のメタデータを提供したり、Story 固有のメタデータを定義できたりする。[1]
- JavaScript API が提供されている。[2]
Ladle の見た目
公式のデモがあるのですぐに触ることができる。
表示はシンプルではあるが殺風景ともいえる。
レポジトリ付属デモ
Controls
Controls は可能な場所でのみアイコンが表示される模様。(公式デモでは見つけられなかった。)
レポジトリ付属のデモをローカルで起動したときには http://localhost:61000/?story=controls--controls でその例を使える。
Storybook と Ladle とで大きく違うところ
Links
モジュールの関数をそのまま使うか hook から渡される関数を使うかで違う。
import { linkTo } from '@storybook/addon-links';
export const first = () => <button onClick={linkTo('Button', 'second')}>Go to "Second"</button>;
import { useLink } from "@ladle/react";
export const Link = () => {
const to = useLink();
return <button onClick={() => to("controls--first")}>Controls</button>;
};
MDX
Ladle ではまだ MDX は使えない。ロードマップにはあるとのこと[1]なので待てば良さそう。
変えている理由はあるのだと思うが、Links Addon を多用しているプロジェクトだと Ladle への乗り換えは面倒くさそう。
CSS の設定 - 通常のグローバルスタイルと CSS の import
設定例: https://github.com/occar421/my-etudes/tree/main/ladle-0_11_0-example-normal-css
".ladle/components.tsx" でグローバルスタイルの CSS ファイルを import するだけでよい。React コンポーネントファイルからそれぞれ import しているファイルは期待通り import してくれる。(Vite の力)
特に読み込んだスタイルを何かしらの機構で分離してくれるわけではない[1]ので、変なグローバルスタイルを当てていると Ladle 提供部分の表示がおかしくなる可能性はある。
グローバルスタイルが適用される図
-
カスケードレイヤーとか使ってると面白かったのだが… ↩︎
(許容した)仕様かと思ったが、bug らしい?スクラップの筆者の勘違いかもしれないが。
CSS の設定 - @emotion/react
新しい JSX トランスフォームを使った書き方において、まだ @emotion/react は使えない。Vite の react プラグインに jsxImportSource
オプションを渡せる余地がない。
@babel/plugin-transform-react-jsx
や @emotion/babel-plugin
を入れて設定しても、(Ladle が指定する何かとの関係からか?)Vite に上書きされてしまう。
HACK として node_modules/@ladle/react/lib/cli/vite-base.js の Vite react プラグインへの引数に jsxImportSource: "@emotion/react",
を入れて起動すると正しく読み込んでくれる。 🙄
HACK 以外の設定例: https://github.com/occar421/my-etudes/tree/main/ladle-0_11_0-example-emotion
この PR のマージにより現在は解決していそう(未検証)
CSS の設定 - TailwindCSS
設定例: https://github.com/occar421/my-etudes/tree/main/ladle-0_11_0-example-tailwind
TailwindCSS は公式ガイドの通り設定したうえで、Ladle は 上記の通常の CSS の場合と全く同じように設定すればよい。
但し、Preflight(グローバルスタイル)が適用されることで Ladle のコントロールの表示がおかしくなっている。
Storybook と比較したときの Ladle の弱点
TODO
サービス・エコシステムの不足 Chromatic, storycap, Figma 連携
メジャーバージョンリリースを経て、今後はあまり独自の動きはなさそうに感じる。
他の方の記事が出てくることに期待して、このスクラップはクローズする。