はじめに
みなさん、バンドルファイルのコード分割行っていますでしょうか。各UIフレームワークが提供もしくは推奨しているコンポーネントの遅延読み込みだったり、バンドラーの設定でチャンク戦略を取って分割を行っている方が多いと思います。
コードの分割を行うと分割したファイルの様子を知りたかったり、不自然に肥大化したファイルの原因を辿ったりするなど分割されたファイルの様子を知りたいケースがいくつか出てきます。
この記事ではViteの環境において分割されたバンドルファイルがどのように分布されているかを可視化するライブラリーを紹介します。
Reactを想定したサンプルコードを使用しますが、Viteを用いるVueなどの他のライブラリでも同様に動きます。
rollup-plugin-visualizer
Viteはesbuildを利用しているというイメージが強いですがesbuildは開発環境でしか用いられておらず、本番ではRollupを用いたバンドルを行っています。Rollupにはファイルの分布を可視化するライブラリがあります。rollup-plugin-visualizerです。先述の通りViteのビルドはRollupを利用することからViteでもこれを利用できます。
導入
ライブラリをインストールします(npmを使いましたが、yarnでもpnpmでも可能です)。
npm install --save-dev rollup-plugin-visualizer
インストール後はvite.config.tsにimportしてpluginsを追加するだけで利用できます。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { visualizer } from 'rollup-plugin-visualizer';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), visualizer()]
})
設定後npm run build
でビルドと同時にstats.htmlを生成してくれます。そのファイルをブラウザで開くと下のように表示されます。
実行したプロジェクトはnpm create vite@latest
で作成したばかりのプロジェクトなので一つのindex.jsにまとまった状態になっています。ブラウザの表示からindex.jsの中に色々なライブラリが入っていてreact-domが多くの割合を占めていることがわかります。領域の大きさがそのライブラリやファイルが占めているファイルの容量そのものを表しています。
コード分離
viteの提供するチャンク戦略(splitVendorChunkPlugin)を利用してコード分離を行った場合の出力を見てみます。この戦略はコードとライブラリをindexとvenderに分割するような戦略です。
import { defineConfig, splitVendorChunkPlugin } from 'vite'
import react from '@vitejs/plugin-react'
import { visualizer } from 'rollup-plugin-visualizer';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), visualizer(), splitVendorChunkPlugin()],
})
小さくて見にくいですが、色によってindexとvenderで分割されています。赤がindex、青がvenderです。コード分割を行なっている成熟されたアプリケーションではもっと綺麗な表示を見ることができると思います(はじめにの画像のような)。
設定
rollup-plugin-visualizerにはさまざまな設定があります。それぞれvisualizer
の引数にオブジェクトとして渡すことで設定が可能です。
filename
出力するファイル名を設定します。後述のtemplateに沿った拡張子にする必要があります。
デフォルトはstat.html
です(templateがdefaultの時の拡張子)。
visualizer({ filename: 'filename.html' })
title
出力されるファイルのタイトルを設定します。デフォルトはRollup Visualizer
です。
visualizer({ title: 'タイトル' })
open
ファイルが作成されたときにデフォルトブラウザで自動で開いてくれる設定をします。デフォルトはfalse
です。
visualizer({ open: true })
template
どのような種類のテンプレートで出力するか設定します。デフォルトはtreemap
です。sunburst
, treemap
, network
, raw-data
, list
を設定することができます。treemap
はデフォルトの表示で、raw-data
はstat.json
に生データを、list
はstats.yml
にデータを出力します。sunburst
の出力は中央(root)から沿って依存しているパッケージ、ファイルを追って確認することができます。
network
はライブラリやファイルの大きさに対応した円があって、それらが依存関係に合わせて繋がっているものが出力されます。
visualizer({ open: true })
gzipSize
レンダリングされたファイルの他にgzipファイルを元にした出力に切り替えできるようにします。デフォルトはfalseです。
ブラウザの左上に出力されたラジオボタンで切り替えできます。
visualizer({ gzipSize: true })
brotliSize
ブラウザの左上に出力されたラジオボタンで切り替えできます。
レンダリングされたファイルの他にbrotliファイルを元にした出力に切り替えできるようにします。デフォルトはfalseです。
visualizer({ brotliSize: true })
emitFile
emitFileを利用した出力に設定します。デフォルトはfalseです。
visualizer({ emitFile: true })
sourcemap
ソースマップを利用してサイズを計算する設定をします。デフォルトはfalseです。オプションの最後に設定する必要があります。ソースマップがなければ警告が出るので注意してください(出力がうまくいきません)。
visualizer({ sourcemap: true })
projectRoot
ルートパスを絶対パスで設定します。デフォルトはprocess.cwd()
です。
visualizer({ projectRoot: '' })
さいごに
この記事ではViteでバンドルファイルの可視化する方法を紹介しました。ファイルの分離が適切に行われているか、巨大になっているファイルのボトルネックの特定と分離であったりに役立つので是非ご利用ください。