Nuxt3でバンドルされたファイルを可視化する

Nuxt3でバンドルされたファイルの可視化方法を調べてみました。

Nuxt3でも可視化できる

Nuxt2では webpack-bundle-analyzer が組み込まれており可視化出来る様になっていました。
Nuxt3でも同様に rollup-plugin-visualizer が組み込まれていて可視化出来るようになっています。

可視化する方法は2つあってそれぞれメリット・デメリットがあるのでお好みの方を選びましょう。

  • nuxiコマンドで解析結果のHTMLを出力
  • ビルド時に解析結果のHTMLを出力

nuxiコマンドで解析結果のHTMLを出力

nuxianalyze コマンドがあるのでそれを使うと可視化できます。
https://nuxt.com/docs/api/commands/analyze

$ npx nuxi analyze --help
Nuxi 3.5.1
> Usage: npx nuxi analyze [--log-level] [--name] [--no-serve] [rootDir]

⋮ Build nuxt and analyze production bundle (experimental)

Use npx nuxi [command] --help to see help for each command

メリットはクライアントサイドの結果とは別にサーバサイドの結果も出力してくれます。
デメリットは解析処理の設定が行えないためデフォルトの解析結果以上の内容を出力したい場合は後述のビルド時に解析結果のHTMLを出力する方法を利用する必要があります。

注意点その1 まだexperimental扱い

3.5.1 現在 experimental 扱いになっています。
ぱっと見ちゃんと使えてそうですが仕様変更があったり削除される可能性もあるので注意が必要です。

注意点その2 analyzeで生成されたファイルはデプロイNG

analyzeコマンドを実行すると最後にこのように表示されます。

 WARN  Do not deploy analyze results! Use nuxi build before deploying.  

analyzeコマンド実行時はproduction用の構成でビルドされるらしいですがデプロイ時はビルドしてからデプロイするようにしましょう。

使い方

何もオプションを指定しないで実行すると解析結果のHTMLを生成した後にサーバが起動するのでプロンプトに表示されるURLを開くと表示されます。
サーバ用とクライアント用の解析結果が別々で生成されるので見たい方をクリックします。

$ npx nuxi analyze

サーバを起動させずに解析結果のHTMLを生成のみを行う場合は --no-serve オプションを指定して実行します。
ファイルは .nuxt/analyze/default 以下に生成されます。

$ npx nuxi analyze --no-serve
$ ls .nuxt/analyze/default 
client.html meta.json   nitro.html

ビルド時に解析結果のHTMLを出力

nuxt.config.ts に解析用の設定を追加するとビルド時に解析結果のHTMLも出力されるようになります。
https://nuxt.com/docs/api/configuration/nuxt-config#analyze

メリットは rollup-plugin-visualizer のオプション を設定出来るので解析結果のカスタマイズができます。
デメリット nuxi analyze では出力されたサーバサイドの解析結果が出力されません。

使い方

ビルドの設定に追加します。

export default defineNuxtConfig({
  build: {
    analyze: true
  }
})

追加後にビルドするとビルドの成果物と一緒に解析結果のHTMLも生成されます。
デフォルトだとルートディレクトリに stats.html というファイル名で生成されます。

解析結果をカスタマイズする場合は true の代わりに rollup-plugin-visualizer のオプション をオブジェクトで指定できます。

export default defineNuxtConfig({
  build: {
    analyze: {
      filename: 'stats.{ext}', // 出力するファイル名
      title: 'Rollup Visualizer', // titleタグの文字列
      open: false, // 解析結果生成後に自動で開くかどうか
      template: 'treemap', // 解析結果のテンプレート
      gzipSize: false, // gzip圧縮後のサイズを計算するかどうか
      brotliSize: false, // Brotli圧縮後のサイズを計算するかどうか
    }
  }
})

関連リンク