🌟

Vite製のアプリケーションにBundle Analyzerを設定する

2021/10/21に公開

概要

ViteでセットアップしたアプリケーションにBundle Analyzerを設定する方法です。

WebpackにはWebpack Bundle Analyzerがあり、Nuxt.jsで開発しているならばnuxt build -aで実行できるようにデフォルトで組み込まれていることから利用したことのある人は多いと思います。

Viteの場合はproduction buildにRollupが用いられているため、自分で設定することが必要です。

本記事ではViteの設定ファイルにRollupのBundle Analyzerを設定する方法を示します。

rollup-plugin-visualizerのインストール

rollup-plugin-visualizerという、まさにWebpackのそれと同様のプラグインがあるため、インストールします。

yarn add -D rollup-plugin-visualizer

vite.config.tsへの設定

vite.config.tsでbuild.rollupOptions.pluginsにRollupの任意のプラグインを設定できます。

vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig(({ mode }) => {
  return {
    build: {
      rollupOptions: {
        plugins: [
          visualizer(),
        ],
      },
    },
  };
});

単にvisualizer()を書き足すだけで設定完了します。

続いてvite buildコマンドを実行すると、カレントディレクトリにstats.htmlが生成されます。

stats.htmlをブラウザで開くと、Webpack Bundle Analyzerに近い見た目の結果が得られていることが確認できます。

スクリーンショット 2021-10-21 19 11 42

より便利な設定

これで基本的な設定は完了しましたが、いささか不便な点が残っています。

  • stats.htmlがgit管理下に置かれるため、.gitignoreの書き換えが必要
  • build実行時に必ずstats.htmlも生成されると、誤って本番環境へデプロイされるリスクがある
  • コマンド実行完了時にブラウザで開いてほしい

以上の欲求を満たすために、以下のように設定をカスタムしてみました。

vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig(({ mode }) => {
  return {
    build: {
      rollupOptions: {
        plugins: [
          mode === 'analyze' &&
            visualizer({
              open: true,
              filename: 'dist/stats.html',
              gzipSize: true,
              brotliSize: true,
            }),
          }),
        ],
      },
    },
  };
});

これで、npx vite build --mode analyzeのようにmodeを指定したときだけ分析が走り、stats.htmlはdist内に配置されるのでGit管理されず、完了時にブラウザで開くのでシームレスです。

manualChunksで1ファイルあたりのバンドルサイズを小さくする

Viteにおけるバンドルサイズ削減の方法の1つを紹介します。

buildを実行した際、以下のようにWarningが表示されます。

dist/assets/create.73b919a4.js      167.35 KiB / gzip: 41.45 KiB
dist/assets/vendor.ca26b2f9.js      767.41 KiB / gzip: 209.36 KiB
dist/assets/index.f17c6159.js       706.40 KiB / gzip: 214.39 KiB

(!) Some chunks are larger than 500 KiB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/guide/en/#outputmanualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

2つ目に指定されているmanualChunksを使うと、手動でチャンクする粒度を制御できるので、1ファイルあたりのバンドルサイズを低減できます。

      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-router-dom', 'react-dom'],
            dateFormatter: ['date-fns']
          }
        },
dist/assets/create.7d7ac1e7.js          117.37 KiB / gzip: 30.61 KiB
dist/assets/index.a620ce54.js           463.65 KiB / gzip: 114.37 KiB
dist/assets/vendor.93948f08.js          320.85 KiB / gzip: 100.01 KiB
dist/assets/index.ba547310.js           706.40 KiB / gzip: 214.39 KiB

(!) Some chunks are larger than 500 KiB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/guide/en/#outputmanualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

もちろんReactであればSuspenseを用いて各ページコンポーネントをLazy loadするなどの工夫も重要ですが、このようにmanualChunksを使うことで、バンドルサイズを低減できます。


最後まで読んでいただきありがとうございました!記事が参考になったらプロテイン代(という名のバッジ)を恵んでください!

マナリンク Tech Blog

Discussion