はじめに
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