Webpack → Vite: Storybookのバンドラー移行
(medium.com/@hong009319)Storybook のバンドラーを Webpack から Vite に移行しました。この過程で複数の問題が連鎖的に発生し、結果として既存の技術スタックを変更する必要がありました。
技術スタックの変更
• [既存の技術スタック] Storybook v6.5, builder-webpack5, Node v18, Yarn 1
• [最終的な技術スタック] Storybook v7, react-vite, Node v18, Pnpm
移行時に発生した問題
1. Webpack 4 と OpenSSL 3 バージョン互換性の問題
-
問題の説明
- builder-webpack5 から builder-vite へ移行する過程で、OpenSSL バージョン互換性の問題が発生
- Webpack 5.61.0 未満のバージョンでは旧バージョンの OpenSSL を使用し、それ以降は OpenSSL 3 を使用
- Storybook v6 は Webpack 4 をデフォルトビルダーとして使用し、Webpack 5 はオプションとして提供
- 当時は Webpack 5 を選択しており、Webpack ^5.9.0 を使用する builder-webpack5 を利用していたため OpenSSL エラーは発生していなかった
- 移行後の builder-vite は Vite でビルドしていても、Storybook v6 ではデフォルトビルダーとして Webpack 4 を使用するため、OpenSSL バージョン互換性の問題が発生
-
解決方法: Storybook v7 へ移行
- Storybook v7 では Vite を使う場合、Storybook 内部で Webpack 4 を使用しないため OpenSSL エラーは発生しない
2. Yarn 1 の hoisting によりバージョンの異なる依存関係が使用される問題
-
問題の説明
@isaacs/cliuiパッケージでは、ESM 形式のstring-width@5と CommonJS(CJS)形式のstring-width@4をstring-width-cjsという alias として使用している- Yarn 1 は重複した依存パッケージをルートの node_modules に hoist するため、パッケージからインストールしていない依存関係にもアクセスできる
string-width@4と@5は複数のパッケージで重複して使われる sub-dependency であるため、ルートの node_modules に hoist されていたstring-widthパッケージのうち、CJS 形式のcli-table3がstring-width@4にアクセスしようとしたが、alias のため同一バージョンが存在せず、ESM 形式のstring-width@5を resolve してしまい、モジュール互換性の問題が発生
-
解決方法: phantom dependency が発生しない pnpm にパッケージマネージャーを変更
1件のコメント
質問。webpackで
esbuild-loaderを使わなかった理由はありますか?回答。
Native ESMの機能を活用するためにViteを使いました。
esbuild-loaderは、Webpackでesbuildを使えるようにするローダーだと理解しています。esbuild-loaderを使えばビルド速度は非常に速くなりますが、それでもなおバンドルの工程を経る必要があります。一方、Native ESMを使うと、使用するモジュールだけをビルドしてブラウザに渡し、モジュールが変更された場合も変更されたモジュールだけをビルドするため、より高速です。
Storybookのように特定のコンポーネントだけを要求するケースでは、Native ESMを使うのが適していると判断し、Viteを使いました。