はじめに
Storybook で Vite を使ってビルドできるようになったので紹介します。
iframe 内のビルドを Webpack から vite に切り替えることで次の利点があります。
- ビルド速度の改善
- HMR の高速化
- アセット処理の自動化
- Vite プロジェクト設定との互換性
- Vite のプラグインエコシステムへのアクセス
コンポーネントが少ない場合、速度の恩恵はあまり感じられない可能性があります。
Webpack と比較すると、ブラウザが表示されるまでのスピードは劇的に向上しますが、
ブラウザ上での読み込みに時間がかかるためです1。
一方、コンポーネントが増えた場合に増加する時間は、抑えられると思います。 また、HMR での再ビルドは明らかな速度の差を感じられると思います。
個人的に vite に切り替える最大の利点は、アセット処理の設定が不要になることです。
Webpack ベースの場合、例えば sass を使うには、それ用の loader を設定する必要があります。
viteであれば、TypeScript、CSS プリプロセッサ、Static Assets の処理などは標準で備えているため設定不要です。
その反面、viteに切り替えることで、一部の Storybook アドオンが使用できなくなる可能性があります。
これは Storybook で webpack 5 を使用する場合にも同じことが言えます。
多くの Storybook アドオンを利用しているプロジェクトでは、十分な検証をしてから切り替えることをおすすめします。
ちなみに以下のアドオンは動作確認しました。
Storybook の準備
説明にはpreactを用います。preact を例にする理由は、preact 環境の場合、少しハマるポイントがあるためです。
まずはプロジェクトの雛形を作成します。
のちに必要になる storybook-builder-vite の peerDependency もインストールしています。
つづいて、Storybook の雛形を生成します。 スクラッチでももちろん環境構築できますが、次のコマンドで雛形を生成できます。
builder オプションに storybook-builder-vite を指定するとついでに storybook-builder-viteもインストールしてくれます。
さてこれで雛形は完成しました。
この時点でのディレクトリ構成は次の通りです。説明に不要なファイルは除いています。
また、package.json には次のコマンドが追加されています。
この段階で start-storybook コマンドを実行しても、Introduction.stories.mdxのレンダリングに失敗します。
preact で mdxファイルを扱う場合には設定が必要です。
プロジェクトにreact や vue を選択した場合、次の作業は不要です。
また、もし preact 環境の場合でも、mdxを扱う必要がなければ、Introduction.stories.mdx を削除することで。
次のセクションを呼び飛ばすことができます。
Preact で mdx ファイルを扱う
preact で mdx ファイルを Storybook で使うために、2つの変更が必要です。
Storybook の設定ファイルを変更する
続いて、.storybook/main.js ファイルを変更します。あとでこのファイルを .ts にして型安全にする方法を紹介します。
storybook-builder-vite によって、viteFinalというフックが追加されます。
このフックから vite の設定を変更できます。
プラグインで @preact/preset-vite を使うように変更します。
ちなみに元々の構成では、以下のプラグインが有効になっています。
- storybook-vite-code-generator-plugin
- mock-core-js
- vite-plugin-mdx
- mdx:transclusion
- storybook-vite-inject-export-order-plugin
これらも引き続き使う必要があるので、Destructuring assignmentによって、plugins にプラグインの配列を代入します。
jsx inject に対応する
@preact/preset-vite によって、[j,t]sxファイルには自動的に import { h, Fragment } from 'preact' が挿入されます。
雛形で Storybook を生成した場合、 生成されたファイルにはすでに import { h, Fragment } from 'preact'が宣言されています。
自動挿入により宣言が重複するので、雛形のすべてファイルから上の宣言を削除します。
これで準備は完了したので、start-storbybook コマンドを実行しましょう。
無事、正常にレンダリングされていると思います。
Storybook の設定ファイルを型安全にする
Storybook の設定ファイルは、デフォルトでは .jsです。
わたしは設定ファイルは何が何でも型安全にしたい病気なので、その方法を紹介します。
現在の状態は次の通りです。
main.js と preview.js は利用するモジュールシステムが異なります。
main.js は Node.js での 利用を前提としているため、 Commonjs を採用しています。
一方、preview.js は ブラウザで実行されるため、 ES modules です。
こちらは TypeScript もサポートされています。
この両方を TypeScrit 化して、 ES modulesで書けるように変更します。
ちなみに、Gatsby なども似たような構成なので、同じ手法で型安全な設定ファイルを定義できます。
main.js を型安全にする
main.js はエントリーポイントなので、このファイルはそのまま残します。
新たに main.ts を作成し、 main.js の内容を ES modules に書き換えます。
このタイミングで chunkSizeWarningLimit を変更するコードを追加しています。
ビルド時のバンドルサイズの警告を抑える目的です。なくても問題ないです。
これに型注釈を与えます。型は storybook-builder-vite からは提供されていないので、自作する必要があります。
Storybook の StorybookConfig 型を拡張する必要があります。
interface ですでに存在するプロパティを拡張する場合は、そのプロパティを一旦 any にする必要があります。
Weaken は私が作っている utilitypesというプロジェクトで提供している便利な型です。
指定したプロパティを any した型を返します。
この記事の作成時はまだ、 beta です。
あとはこの型を型注釈で指定します。ファイル全体は次のようになります。
続いて、 main.js から main.ts をインポートします。
main.jsは Commonjs なので、 通常 TypeScript も ES modules も処理できません。
これを実現するために、 esbuild-registerというパッケージを使います。
esbuild-registerは ts-node の esbuild 版です。型のチェックはありません。早いです。
main.js は次のようになります。
main.js は単なるエントリーポイントで、実際の設定は型安全に main.ts に書けるというわけです。
preview.js を型安全にする
preview.js の方は、 ES modules ですし、 TypeScripts も処理できるのでやることはほぼありません。
- ファイルの拡張子を
.tsもしくは.tsxへ変更 - Storybook の型を型注釈する
こんな感じになります。
Storybook は大量のファイルを提供しているので、型を見つけるのが大変でした💦。
これで型安全な開発ができますね。
プロダクションコードをプレビューする
完全におまけです。ビルド済みのコードを確認したいことありますよね。
Webpackから vite へ切り替えるような場合はなおさらです。
Storybook にはプレビュー用のコマンドが用意されていません。 なので、静的ファイルサーバーを自分で建てなければなりません。といっても簡単ですが。
npx http-server storybook-static
これでプレビューができますね。
- Storybook のバンドルサイズはかなり大きいです。↩
Edit this page on GitHub
