コンテンツへスキップ

依存関係の事前バンドル

初めて vite を実行すると、Vite はプロジェクトの依存関係を事前バンドルしてから、サイトをローカルに読み込みます。これはデフォルトで自動的かつ透過的に行われます。

理由

これは、Vite が「依存関係の事前バンドル」と呼ぶものです。このプロセスには 2 つの目的があります。

  1. CommonJS および UMD の互換性: 開発中、Vite の開発サーバーはすべてのコードをネイティブ ESM として提供します。そのため、Vite は CommonJS または UMD として提供される依存関係を最初に ESM に変換する必要があります。

    CommonJS の依存関係を変換する際、Vite は賢いインポート分析を実行し、CommonJS モジュールへの名前付きインポートが、エクスポートが動的に割り当てられている場合でも (例: React) 期待通りに機能するようにします。

    js
    // works as expected
    import React, { useState } from 'react'
  2. パフォーマンス: Vite は、多くの内部モジュールを持つ ESM 依存関係を単一のモジュールに変換して、その後のページ読み込みパフォーマンスを向上させます。

    一部のパッケージは、ES モジュールビルドを互いにインポートし合う多数の個別のファイルとして提供しています。たとえば、lodash-es には 600 以上の内部モジュールがありますimport { debounce } from 'lodash-es' を実行すると、ブラウザは同時に 600 以上の HTTP リクエストを発行します!サーバーがこれらを処理するのに問題がないとしても、大量のリクエストはブラウザ側でネットワークの輻輳を引き起こし、ページの読み込みを著しく遅くします。

    lodash-es を単一のモジュールに事前バンドルすることで、必要な HTTP リクエストは 1 つだけになります!

注意

依存関係の事前バンドルは開発モードでのみ適用され、esbuild を使用して依存関係を ESM に変換します。プロダクションビルドでは、代わりに @rollup/plugin-commonjs が使用されます。

自動依存関係検出

既存のキャッシュが見つからない場合、Vite はソースコードをクロールして依存関係のインポート (つまり、node_modules から解決されることを期待する「ベアインポート」) を自動的に検出し、これらの見つかったインポートを事前バンドルのエントリポイントとして使用します。事前バンドルは esbuild で実行されるため、通常は非常に高速です。

サーバーが既に開始された後、キャッシュにない新しい依存関係のインポートが検出された場合、Vite は必要に応じて依存関係バンドルプロセスを再実行し、ページをリロードします。

モノレポとリンクされた依存関係

モノレポ設定では、依存関係は同じリポジトリからのリンクされたパッケージである場合があります。Vite は node_modules から解決されない依存関係を自動的に検出し、リンクされた依存関係をソースコードとして扱います。リンクされた依存関係をバンドルしようとはせず、代わりにリンクされた依存関係の依存関係リストを分析します。

ただし、これにはリンクされた依存関係が ESM としてエクスポートされている必要があります。そうでない場合は、設定で optimizeDeps.includebuild.commonjsOptions.include に依存関係を追加できます。

vite.config.js
js
export default 
defineConfig
({
optimizeDeps
: {
include
: ['linked-dep'],
},
build
: {
commonjsOptions
: {
include
: [/linked-dep/, /node_modules/],
}, }, })

リンクされた依存関係に変更を加えた場合、変更を有効にするには、--force コマンドラインオプションを指定して開発サーバーを再起動します。

動作のカスタマイズ

デフォルトの依存関係検出ヒューリスティックが常に望ましいとは限りません。リストから依存関係を明示的に含める/除外したい場合は、optimizeDeps 設定オプションを使用してください。

optimizeDeps.include または optimizeDeps.exclude の一般的なユースケースは、ソースコードで直接検出できないインポートがある場合です。たとえば、インポートがプラグイントランスフォームの結果として作成される場合などです。これは、Vite が最初のスキャンでインポートを検出できないことを意味します。ブラウザによってファイルが要求され、変換された後にのみ検出できます。これにより、サーバー起動直後にサーバーがすぐに再バンドルされます。

これに対処するには includeexclude の両方を使用できます。依存関係が大きい (多くの内部モジュールがある) または CommonJS である場合は、含めるべきです。依存関係が小さく、すでに有効な ESM である場合は、除外してブラウザに直接ロードさせることができます。

optimizeDeps.esbuildOptions オプションを使用して esbuild をさらにカスタマイズすることもできます。たとえば、依存関係内の特殊なファイルを処理するための esbuild プラグインを追加したり、ビルド target を変更したりできます。

キャッシュ

ファイルシステムキャッシュ

Vite は、事前バンドルされた依存関係を node_modules/.vite にキャッシュします。Vite は、いくつかのソースに基づいて事前バンドルステップを再実行する必要があるかどうかを判断します。

  • パッケージマネージャーのロックファイルの内容 (例: package-lock.jsonyarn.lockpnpm-lock.yaml、または bun.lockb)。
  • パッチフォルダの変更時間。
  • 存在する場合は、vite.config.js の関連フィールド。
  • NODE_ENV の値。

上記のいずれかが変更された場合にのみ、事前バンドルステップを再実行する必要があります。

何らかの理由で Vite に依存関係を再バンドルさせたい場合は、--force コマンドラインオプションを指定して開発サーバーを起動するか、手動で node_modules/.vite キャッシュディレクトリを削除することができます。

ブラウザキャッシュ

解決された依存関係のリクエストは、開発中のページリロードパフォーマンスを向上させるために、HTTP ヘッダー max-age=31536000,immutable で強力にキャッシュされます。一度キャッシュされると、これらのリクエストは開発サーバーに再度ヒットすることはありません。異なるバージョンがインストールされた場合 (パッケージマネージャーのロックファイルに反映されます)、追加されたバージョンクエリによって自動的に無効化されます。ローカルで編集して依存関係をデバッグしたい場合は、次のことができます。

  1. ブラウザの開発者ツールのネットワークタブから一時的にキャッシュを無効にします。
  2. --force フラグを指定して Vite 開発サーバーを再起動し、依存関係を再バンドルします。
  3. ページをリロードします。

MIT ライセンスで公開。(083ff36d)