特徴
基本的に、Vite を使用した開発は静的ファイルサーバーを使用した時とそれほど変わりません。しかし、Vite はバンドラーベースのセットアップで一般的な機能をサポートするためにネイティブ ESM をインポートすることで様々な拡張機能を提供します。
npm の依存関係の解決と事前バンドル
ネイティブ ES のインポートは次のような生のモジュールをサポートしていません:
import { someMethod } from 'my-dep'
上のようなコードはブラウザーでエラーになります。Vite は提供される全てのソースファイルでこのような生のモジュールのインポートを検出し以下を実行します:
事前バンドル はページの読み込み速度を改善し、CommonJS / UMD モジュールを ESM に変換します。事前バンドルは esbuild で実行され、Vite のコールドスタート時間をどんな JavaScript ベースのバンドラーよりも大幅に高速にします。
インポートを
/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd
のように書き換えることでブラウザーが正しくモジュールをインポートできるようにします。
依存関係は積極的にキャッシュされます
Vite は HTTP ヘッダーを介して依存関係のリクエストをキャッシュするため、依存関係をローカルで編集/デバッグする場合は、ここの手順に従ってください。
Hot Module Replacement
Vite はネイティブ ESM を介して HMR API を提供します。HMR 機能を備えたフレームワークは、API を活用して、ページを再読み込みしたり、アプリケーションの状態を損失することなく即座に正確な更新を提供できます。Vite は Vue の単一ファイルコンポーネント および React Fast Refresh に対しての HMR 統合を提供します。@prefresh/vite を介した Preact の統合された公式のライブラリーもあります。
これらを手動で設定する必要がないことには注意してください - create-vite
を介してアプリケーションを作成する場合、これらはすでに構成されています。
TypeScript
Vite は .ts
ファイルをインポートすることをサポートしています。
トランスパイルのみ
Vite は .ts
ファイルのトランスパイルを行うだけで、型チェックは行わないことに注意してください。型チェックは IDE やビルドプロセスで行われることを想定しています。
Vite が変換処理の一部として型チェックを行わないのは、この 2 つのジョブが根本的に異なる動作をするからです。トランスパイルはファイル単位で行うことができ、Vite のオンデマンドコンパイルモデルと完全に調和しています。これに対して、型チェックはモジュールグラフ全体についての知識が必要です。Vite の変換パイプラインに型チェックを組み込むと、必然的に Vite の利点であるスピードが損なわれてしまいます。
Vite の仕事は、ソースモジュールをできるだけ速くブラウザーで実行できる形にすることです。そのため、Vite の変換パイプラインから静的解析チェックを切り離すことをお勧めします。この原則は、ESLint のような他の静的解析チェックにも当てはまります。
プロダクションビルドの場合は、Vite のビルドコマンドに加えて、
tsc --noEmit
を実行できます。開発中、IDE のヒント以上が必要な場合は、別プロセスで
tsc --noEmit --watch
を実行するか、型エラーをブラウザーに直接報告させたい場合は vite-plugin-checker を使用することをおすすめします。
Vite は esbuild を用いて TypeScript を JavaScript に変換します。これは、vanilla の tsc
よりも約 20〜30 倍速く、HMR の更新は 50 ミリ秒未満でブラウザーに反映されます
型のみのインポートやエクスポート構文を使用すると、型のみのインポートが正しくバンドルされないなどの潜在的な問題を回避できます。例えば:
import type { T } from 'only/types'
export type { T }
TypeScript コンパイラーオプション
tsconfig.json
の compilerOptions
にあるいくつかの設定フィールドには、特別な注意が必要です。
isolatedModules
true
に設定する必要があります。
esbuild
は型情報なしにトランスパイルを行うだけなので、const enum や暗黙の型のみのインポートなどの特定の機能をサポートしていないからです。
隔離されたトランスパイルで動作しない機能を TS が警告するように、tsconfig.json
の compilerOptions
で "isolatedModules": true
を設定する必要があります。
もし依存関係が "isolatedModules": true
でうまく動作しない場合は、"skipLibCheck": true
を使用すると、アップストリームで修正されるまで一時的にエラーを抑制できます。
useDefineForClassFields
Vite 2.5.0 からは、TypeScript ターゲットが ESNext
か ES2022
以上の場合、デフォルト値は true
になります。これは tsc
4.3.2 以降の動作と一致しています。また、これは ECMAScript の標準的なランタイムの動作でもあります。
他の TypeScript ターゲットはデフォルトで false
になります。
しかし、他のプログラミング言語や古いバージョンの TypeScript を使用している人にとっては直感的に理解できないかもしれません。 移行の詳細については、TypeScript 3.7 リリースノートを参照してください。
クラスフィールドに大きく依存しているライブラリーを使用している場合は、そのライブラリーが意図している使い方に注意してください。
MobX などのほとんどのライブラリーは "useDefineForClassFields": true
を想定しています。
しかし、lit-element
など、まだこの新しいデフォルトに移行していないライブラリーもあります。これらの場合は、明示的に useDefineForClassFields
を false
に設定してください。
target
Vite は esbuild
と同じ動作に従い、tsconfig.json
内の target
の値を無視します。
開発中に target を指定するには esbuild.target
オプションを使用することができ、トランスパイルを最小限に抑えるためにデフォルトで esnext
に設定されます。ビルドでは、build.target
オプションが優先され、必要に応じて設定することができます。
useDefineForClassFields
tsconfig.json
内の target
が ESNext
または ES2022
以降でない場合、または tsconfig.json
ファイルがない場合、useDefineForClassFields
のデフォルトは false
になり、esbuild.target
のデフォルト値が esnext
の場合に問題が発生する可能性があります。これは静的初期化ブロックにトランスパイルされる可能性があり、ブラウザーでサポートされていない可能性があります。
そのため、tsconfig.json
を設定する際には、target
を ESNext
または ES2022
以降に設定するか、useDefineForClassFields
を明示的に true
に設定することをおすすめします。
ビルド結果に影響するその他のコンパイラーオプション
extends
importsNotUsedAsValues
preserveValueImports
verbatimModuleSyntax
jsx
jsxFactory
jsxFragmentFactory
jsxImportSource
experimentalDecorators
alwaysStrict
skipLibCheck
Vite のスターターテンプレートでは依存関係の型チェックを避けるため、デフォルトで "skipLibCheck": "true"
となっています。これは TypeScript の特定のバージョンや設定のみをサポートするように選択できるようにするためです。詳しくは vuejs/vue-cli#5688 を参照してください。
クライアントでの型
Vite はデフォルトでは Node.js の API を提供します。Vite でクライアント用のコードを使用するには d.ts
の定義ファイルを追加します:
/// <reference types="vite/client" />
または、tsconfig.json
内の compilerOptions.types
に vite/client
を追加することもできます:
{
"compilerOptions": {
"types": ["vite/client"]
}
}
これにより次のことが提供されます:
TIP
デフォルトの型を上書きするためには、自身の型を含む型定義ファイルを追加します。その後、vite/client
の前に型参照を追加してください。
例えば、*.svg
のデフォルトインポートを React コンポーネントにする場合:
vite-env-override.d.ts
(自身の型を含むファイル):tsdeclare module '*.svg' { const content: React.FC<React.SVGProps<SVGElement>> export default content }
vite/client
への参照を含むファイル:ts/// <reference types="./vite-env-override.d.ts" /> /// <reference types="vite/client" />
HTML
HTML ファイルは、Vite プロジェクトの中心に位置し、アプリケーションのエントリーポイントとして機能し、シングルページアプリケーションおよびマルチページアプリケーションの構築をシンプルにします。
プロジェクトルート内の HTML ファイルは、それぞれのディレクトリパスで直接アクセスできます:
<root>/index.html
->http://localhost:5173/
<root>/about.html
->http://localhost:5173/about.html
<root>/blog/index.html
->http://localhost:5173/blog/index.html
<script type="module" src>
や <link href>
などの HTML 要素によって参照されるアセットは、アプリの一部として処理され、バンドルされます。サポートされている要素の完全なリストは次のとおりです:
<audio src>
<embed src>
<img src>
と<img srcset>
<image src>
<input src>
<link href>
と<link imagesrcset>
<object data>
<script type="module" src>
<source src>
と<source srcset>
<track src>
<use href>
と<use xlink:href>
<video src>
と<video poster>
<meta content>
name
属性がmsapplication-tileimage
、msapplication-square70x70logo
、msapplication-square150x150logo
、msapplication-wide310x150logo
、msapplication-square310x310logo
、msapplication-config
、twitter:image
に一致する場合のみ- または、
property
属性がog:image
、og:image:url
、og:image:secure_url
、og:audio
、og:audio:secure_url
、og:video
、og:video:secure_url
に一致する場合のみ
<!doctype html>
<html>
<head>
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<img src="/src/images/logo.svg" alt="logo" />
<script type="module" src="/src/main.js"></script>
</body>
</html>
特定の要素の HTML 処理をオプトアウトするには、その要素に vite-ignore
属性を追加します。これは、外部アセットや CDN を参照する際に便利です。
Vue
Vite は Vue に対して最高のサポートをします:
- Vue 3 SFC はこちら @vitejs/plugin-vue
- Vue 3 JSX はこちら @vitejs/plugin-vue-jsx
- Vue 2.7 SFC はこちら @vitejs/plugin-vue2
- Vue 2.7 JSX はこちら @vitejs/plugin-vue2-jsx
JSX
.jsx
と .tsx
も標準サポートされます。JSX のトランスパイルも esbuild を介して行われます。
Vue を使用している人は公式の @vitejs/plugin-vue-jsx プラグインを使用するべきです。これは、HMR、グローバルコンポーネント解決、ディレクティブ、スロットなど、Vue 3 の固有の機能を提供します。
React や Vue 以外で JSX を使用している場合は、esbuild
オプション を使用してカスタムの jsxFactory
および jsxFragment
を設定できます。例えば、Preact の場合:
import { defineConfig } from 'vite'
export default defineConfig({
esbuild: {
jsxFactory: 'h',
jsxFragment: 'Fragment',
},
})
さらに詳しく知りたい場合は esbuild docs を見てください。
また、jsxInject
(Vite のみのオプション)を使用して JSX ヘルパーを挿入し、手動インポートを回避できます。
import { defineConfig } from 'vite'
export default defineConfig({
esbuild: {
jsxInject: `import React from 'react'`,
},
})
CSS
.css
ファイルをインポートすると、HMR をサポートする <style>
タグを介してそのコンテンツがページに挿入されます。
@import
のインライン化と書き換え
Vite は、postcss-import
を介した CSS @import
のインライン化をサポートするように事前構成されています。CSS @import
では、Vite エイリアスも尊重されます。さらに、インポートされたファイルが異なるディレクトリーにある場合でも、すべての CSS url()
参照は、正確性を確保するために常に自動的に書き換えられます。
@import
エイリアスと URL の書き換えは Sass ファイルと Less ファイルでもサポートされています(CSS Pre-processorsを参照)。
PostCSS
もしプロジェクトに有効な PostCSS が含まれている場合(postcss-load-config でサポートされている任意の形式、例: postcss.config.js
)、インポートされたすべての CSS に自動的に適用されます。
CSS の圧縮は PostCSS の後に実行され、build.cssTarget
オプションを使用することに注意してください。
CSS Modules
.module.css
で終わる全ての CSS ファイルは全て CSS modules file とみなされます。このようなファイルをインポートすると、対応するモジュールオブジェクトが返されます:
.red {
color: red;
}
import classes from './example.module.css'
document.getElementById('foo').className = classes.red
CSS モジュールの動作は css.modules
オプション により設定できます。
css.modules.localsConvention
がキャメルケースローカルを有効にするように設定されている場合(例:localsConvention: 'camelCaseOnly'
)、名前付きインポートを使用することもできます:
// .apply-color -> applyColor
import { applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor
CSS プリプロセッサー
Vite は最新のブラウザーのみを対象としているため、CSSWG ドラフト(postcss-nesting など)を実装する PostCSS プラグインでネイティブ CSS 変数を使用し、将来の標準に準拠したプレーンな CSS を作成することをお勧めします。
とは言うものの、Vite は .scss
、.sass
、.less
、.styl
、.stylus
ファイルの組み込みサポートを提供します。それらに Vite 固有のプラグインをインストールする必要はありませんが、対応するプリプロセッサー自体をインストールする必要があります。
# .scss and .sass
npm add -D sass-embedded # または sass
# .less
npm add -D less
# .styl and .stylus
npm add -D stylus
もし Vue で単一ファイルコンポーネントを使用している場合、これにより、<style lang="sass">
なども自動的に有効になります。
Vite は、Sass および Less の @import
解決を改善し、Vite エイリアスも尊重されるようにします。さらに、ルートファイルとは異なるディレクトリーにあるインポートされた Sass / Less ファイル内の相対的な url()
の参照も、正確性を確保するために自動的に書き換えられます。
@import
エイリアスと URL の書き換えは、API の制約のため、Stylus ではサポートされていません。
ファイル拡張子の前に .module
を付けることで、プリプロセッサーと組み合わせて CSS モジュールを使用することもできます(例:style.module.scss
)。
ページへの CSS 注入の無効化
CSS コンテンツの自動注入は ?inline
クエリーパラメータでオフにできます。この場合、処理された CSS 文字列は通常通りモジュールのデフォルトエクスポートとして返されますが、スタイルはページに注入されません。
import './foo.css' // ページに注入される
import otherStyles from './bar.css?inline' // 注入されない
注意
Vite 5 以降、CSS ファイルからのデフォルトインポートおよび名前付きインポート(例:import style from './foo.css'
)は削除されました。代わりに ?inline
クエリーを使用してください。
Lightning CSS
Vite 4.4 から、Lightning CSS の実験的なサポートがあります。設定ファイルに css.transformer: 'lightningcss'
を追加し、オプションの lightningcss
依存関係をインストールすることで有効にできます:
npm add -D lightningcss
有効にすると、CSS ファイルは PostCSS の代わりに Lightning CSS によって処理されます。設定するには、Lightning CSS のオプションを css.lightningcss
に渡します。
CSS Modules を設定するには、css.modules
(PostCSS が CSS モジュールを処理する方法の設定)の代わりに css.lightningcss.cssModules
を使用します。
デフォルトでは、Vite は CSS の圧縮に esbuild を使用します。build.cssMinify: 'lightningcss'
を使用することで、Lightning CSS を CSS の圧縮に使用できます。
NOTE
Lightning CSS 使用時は、CSS プリプロセッサーはサポートされていません。
静的なアセット
静的アセットをインポートすると、提供時に解決されたパブリック URL が返されます:
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl
特別なクエリーにより、アセットの読み込み方法を変更できます:
// アセットを URL として明示的にロードする
import assetAsURL from './asset.js?url'
// アセットを文字列として明示的にロードする
import assetAsString from './shader.glsl?raw'
// Web ワーカーをロードする
import Worker from './worker.js?worker'
// ビルド時に base64 文字列としてインライン化された Web ワーカー
import InlineWorker from './worker.js?worker&inline'
詳しくは 静的アセットの取り扱い を見てください。
JSON
JSON ファイルは直接インポートできます - また、名前付きインポートもサポートされています:
// オブジェクト全体をインポートする場合
import json from './example.json'
// 名前付きエクスポートとしてルートフィールドをインポートします - ツリーシェイクに役立ちます!
import { field } from './example.json'
Glob のインポート
Vite は、特別な import.meta.glob
関数を介してファイルシステムから複数のモジュールをインポートすることをサポートしています:
const modules = import.meta.glob('./dir/*.js')
上のコードは以下のように変換されます:
// vite によって生成されたコード
const modules = {
'./dir/foo.js': () => import('./dir/foo.js'),
'./dir/bar.js': () => import('./dir/bar.js'),
}
次に、modules
オブジェクトのキーを繰り返し処理して、対応するモジュールにアクセスできます:
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod)
})
}
一致したファイルはデフォルトで動的インポートを介して遅延ロードされ、ビルド中に個別のチャンクに分割されます。もしあなたがすべてのモジュールを直接インポートする場合(たとえば、最初に適用されるこれらのモジュールの副作用に依存する場合)、代わりに第 2 引数に { eager: true }
を渡すことができます:
const modules = import.meta.glob('./dir/*.js', { eager: true })
上のコードは以下のように変換されます:
// vite によって生成されたコード
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1,
}
マルチパターン
第 1 引数は下記の例のように glob の配列を指定できます
const modules = import.meta.glob(['./dir/*.js', './another/*.js'])
ネガティブパターン
ネガティブ glob パターンもサポートされています(接頭辞は !
)。一部のファイルを結果から無視させるには、最初の引数に除外 glob パターンを追加します:
const modules = import.meta.glob(['./dir/*.js', '!**/bar.js'])
// vite によって生成されたコード
const modules = {
'./dir/foo.js': () => import('./dir/foo.js'),
}
名前付きインポート
import
オプションでモジュールの一部だけをインポートすることも可能です。
const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
// vite によって生成されたコード
const modules = {
'./dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
'./dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup),
}
eager
と組み合わせると、それらのモジュールのツリーシェイキングを有効にすることも可能です。
const modules = import.meta.glob('./dir/*.js', {
import: 'setup',
eager: true,
})
// vite によって生成されたコード:
import { setup as __glob__0_0 } from './dir/foo.js'
import { setup as __glob__0_1 } from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1,
}
default エクスポートをインポートするには import
に default
を設定します。
const modules = import.meta.glob('./dir/*.js', {
import: 'default',
eager: true,
})
// vite によって生成されたコード:
import __glob__0_0 from './dir/foo.js'
import __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1,
}
カスタムクエリー
また、query
オプションを使用すると、クエリーをインポートに指定することもできます。たとえば、アセットを文字列としてまたは url としてインポートするには、次のように書きます:
const moduleStrings = import.meta.glob('./dir/*.svg', {
query: '?raw',
import: 'default',
})
const moduleUrls = import.meta.glob('./dir/*.svg', {
query: '?url',
import: 'default',
})
// vite によって生成されるコード:
const moduleStrings = {
'./dir/foo.svg': () => import('./dir/foo.js?raw').then((m) => m['default']),
'./dir/bar.svg': () => import('./dir/bar.js?raw').then((m) => m['default']),
}
const moduleUrls = {
'./dir/foo.svg': () => import('./dir/foo.js?url').then((m) => m['default']),
'./dir/bar.svg': () => import('./dir/bar.js?url').then((m) => m['default']),
}
他のプラグインが使用するカスタムクエリーを指定することもできます:
const modules = import.meta.glob('./dir/*.js', {
query: { foo: 'bar', bar: true },
})
Glob インポートの注意事項
注意点:
- これは Vite のみの機能で、Web または ES の標準ではありません。
- Glob パターンはインポート指定子のように扱われます。相対パス(
./
で始まる)か絶対パス(/
で始まり、プロジェクトルートに対して相対的に解決される)、またはエイリアスのパス(resolve.alias
オプション 参照)のいずれかでなければなりません。 - Glob のマッチングは
tinyglobby
を介して行われます。 - また、
import.meta.glob
の引数はすべてリテラル構文として渡さなければならないことに注意が必要です。変数や式は使えません。
Dynamic Import
glob import と同様に、 Vite は変数を使った動的インポートをサポートしています。
const module = await import(`./dir/${file}.js`)
変数は 1 階層分のファイル名しか表さない点に注意してください。file
が 'foo/bar'
の場合、インポートは失敗します。より高度な使い方をしたい場合は、glob import の機能を使うことができます。
WebAssembly
?init
を使うことでプリコンパイルされた .wasm
ファイルをインポートできます。 デフォルトのエクスポートは、WebAssembly.Instance
の Promise を返す初期化関数になります:
import init from './example.wasm?init'
init().then((instance) => {
instance.exports.test()
})
init 関数は、第 2 引数として WebAssembly.instantiate
に渡される importObject を受け取ることもできます:
init({
imports: {
someFunc: () => {
/* ... */
},
},
}).then(() => {
/* ... */
})
本番ビルドでは、assetInlineLimit
よりも小さい .wasm
ファイルが base64 文字列としてインライン化されます。それ以外の場合は、静的アセットとして扱われ、オンデマンドでフェッチされます。
注意
WebAssembly の ES モジュール統合の提案は現時点ではサポートしていません。 vite-plugin-wasm
か、もしくは他のコミュニティーのプラグインを使用して対処してください。
WebAssembly モジュールへのアクセス
もし Module
オブジェクトにアクセスする必要がある場合、例えば複数回インスタンス化する場合は、明示的な URL のインポートを使用してアセットを解決してから、インスタンス化を実行してください:
import wasmUrl from 'foo.wasm?url'
const main = async () => {
const responsePromise = fetch(wasmUrl)
const { module, instance } =
await WebAssembly.instantiateStreaming(responsePromise)
/* ... */
}
main()
Node.js でモジュールをフェッチする
SSR では、?init
インポートの一部として発生する fetch()
は TypeError: Invalid URL
で失敗する可能性があります。 SSR での wasm のサポートの issue を参照してください。
プロジェクトのベースが現在のディレクトリーであると仮定した場合の代替案を以下に示します:
import wasmUrl from 'foo.wasm?url'
import { readFile } from 'node:fs/promises'
const main = async () => {
const resolvedUrl = (await import('./test/boot.test.wasm?url')).default
const buffer = await readFile('.' + resolvedUrl)
const { instance } = await WebAssembly.instantiate(buffer, {
/* ... */
})
/* ... */
}
main()
Web Workers
コンストラクターによるインポート
ワーカースクリプトは new Worker()
や new SharedWorker()
を使用することでインポートできます。サフィックスによるインポートと比べ、より標準的で推奨されるワーカー作成方法となります。
const worker = new Worker(new URL('./worker.js', import.meta.url))
ワーカーコンストラクターはオプションを受け取り、「モジュール」ワーカーとして作成することも可能です:
const worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module',
})
ワーカーの検出は new Worker()
宣言内で直接 new URL()
コンストラクターが使用される場合にのみ機能します。さらに、すべてのオプションパラメーターは静的な値(つまり、文字列リテラル)でなければなりません。
クエリーサフィックスによるインポート
インポートリクエストに ?worker
もしくは ?sharedworker
を追加することで、Web ワーカースクリプトを直接インポートできます。デフォルトのエクスポートはカスタムワーカーコンストラクターになります:
import MyWorker from './worker?worker'
const worker = new MyWorker()
ワーカースクリプトは、importScripts()
の代わりに ESM の import
ステートメントを使用することもできます。注意: 開発中はブラウザーのネイティブサポートに依存しますが、プロダクションビルドではコンパイルされます。
デフォルトでは、ワーカースクリプトは本番ビルドで個別のチャンクとして出力されます。ワーカーを base64 文字列としてインライン化する場合は、inline
クエリーを追加します:
import MyWorker from './worker?worker&inline'
ワーカーを URL として取得したい場合は、url
クエリーを追加してください:
import MyWorker from './worker?worker&url'
すべてのワーカーをバンドルする設定についての詳細は Worker Options を見てください。
コンテンツセキュリティポリシー(CSP)
CSP をデプロイするには、Vite 内部の理由により、特定のディレクティブまたは設定を行う必要があります。
'nonce-{RANDOM}'
html.cspNonce
が設定された場合、Vite は任意の <script>
および <style>
タグに加えて、スタイルシートおよびモジュールプリロードのための <link>
タグに、指定された値を持つ nonce 属性を追加します。<style>
などの他のタグには nonce 属性を追加しないことに注意してください。それに加えて、このオプションを設定すると、Vite が meta タグ(<meta property="csp-nonce" nonce="PLACEHOLDER" />
)を挿入するようになります。
property="csp-nonce"
を持つ meta タグの nonce の値は、Vite により開発中とビルド後のいずれでも必要なときに利用されます。
WARNING
各リクエストごとにユニークな値を持つように、プレースホルダーを必ず置換してください。これはリソースポリシーの回避を防ぐために重要です。もし置換しなければ、簡単に回避されてしまいます。
data:
デフォルトでは、Vite はビルド時に小さなアセットをデータ URI としてインライン化します。関連ディレクティブに対して data:
を許可するか(例: img-src
、font-src
)、設定 build.assetsInlineLimit: 0
により無効化する必要があります。
WARNING
script-src
に対して data:
を許可してはいけません。任意のスクリプトのインジェクションを許してしまうことになります。
ビルドの最適化
以下にリストされている機能は、ビルドプロセスの一部として自動的に適用され、無効にする場合を除いて、明示的に設定する必要はありません。
CSS のコード分割
Vite は、非同期チャンク内のモジュールによって使用される CSS を自動的に抽出し、そのチャンクに対応するファイルを個別に生成します。CSS ファイルは、関連付けられた非同期チャンクが読み込まれるときに <link>
タグを介して自動的に読み込まれ、FOUC を回避するために、CSS が読み込まれた後にのみ非同期チャンクが評価されることが保証されます。
もしすべての CSS を 1 つのファイルに抽出したい場合は、build.cssCodeSplit
を false
に設定することで、CSS コードの分割を無効にできます。
プリロードディレクティブの生成
Vite は、エントリーチャンクとそこから直接インポートされたチャンクの <link rel="modulepreload">
ディレクティブをビルドされた HTML に自動的に生成します。
非同期チャンク読み込みの最適化
実際のアプリケーションでは、Rollup は「共通の」チャンク(2 つ以上の他のチャンク間で共有されるコード)を生成することがよくあります。動的インポートと組み合わせると、次のシナリオが発生するのが非常に一般的です。
最適化されていないシナリオでは、非同期チャンク A
がインポートされると、ブラウザーは、共通チャンク C
も必要と判断する前に、A
を要求して解析する必要があります。これにより、余分なネットワークラウンドトリップが発生します。
Entry ---> A ---> C
Vite は、プリロードステップを使用してコード分割動的インポート呼び出しを自動的に書き換え、A
が要求されたときに、C
が並列にフェッチされるようにします:
Entry ---> (A + C)
これは C
がさらにインポートする可能性があり、最適化されていないシナリオではさらに多くのラウンドトリップが発生します。Vite の最適化は、すべての直接インポートをトレースして、インポートの深さに関係なく、ラウンドトリップを完全に排除します。