コンテンツへスキップ

静的アセットの処理

アセットを URL としてインポートする

静的アセットをインポートすると、それが配信されるときに解決されたパブリック URL が返されます

js
import 
imgUrl
from './img.png'
document
.
getElementById
('hero-img').src =
imgUrl

例えば、開発中は imgUrl/src/img.png になり、本番ビルドでは /assets/img.2d8efhg.png になります。

この動作は webpack の file-loader に似ています。違いは、インポートが絶対パブリックパス (開発中はプロジェクトルートに基づく) または相対パスのいずれかを使用できることです。

  • CSS の url() 参照も同様に扱われます。

  • Vue プラグインを使用している場合、Vue SFC テンプレート内のアセット参照は自動的にインポートに変換されます。

  • 一般的な画像、メディア、フォントのファイルタイプは自動的にアセットとして検出されます。内部リストは assetsInclude オプションを使用して拡張できます。

  • 参照されるアセットはビルドのアセットグラフの一部として含まれ、ハッシュ化されたファイル名が付けられ、最適化のためにプラグインによって処理できます。

  • assetsInlineLimit オプションよりも小さいバイト数アセットは、base64 データ URL としてインライン化されます。

  • Git LFS プレースホルダーは、それらが表すファイルのコンテンツを含まないため、自動的にインライン化から除外されます。インライン化を行うには、ビルド前に Git LFS を介してファイルコンテンツをダウンロードしてください。

  • TypeScript は、デフォルトでは静的アセットのインポートを有効なモジュールとして認識しません。これを修正するには、vite/client を含めます。

url() を介した SVG のインライン化

手動で構築された url() に SVG の URL を渡す場合、変数は二重引用符で囲む必要があります。

js
import 
imgUrl
from './img.svg'
document
.
getElementById
('hero-img').
style
.
background
= `url("${
imgUrl
}")`

明示的な URL インポート

内部リストまたは assetsInclude に含まれていないアセットは、?url サフィックスを使用して URL として明示的にインポートできます。これは、例えば、Houdini Paint Worklets をインポートするのに役立ちます。

js
import 
workletURL
from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(
workletURL
)

明示的なインライン処理

アセットは、それぞれ ?inline または ?no-inline サフィックスを使用して、インライン化またはインライン化なしで明示的にインポートできます。

js
import 
imgUrl1
from './img.svg?no-inline'
import
imgUrl2
from './img.png?inline'

アセットを文字列としてインポートする

アセットは ?raw サフィックスを使用して文字列としてインポートできます。

js
import 
shaderString
from './shader.glsl?raw'

スクリプトをワーカーとしてインポートする

スクリプトは、?worker または ?sharedworker サフィックスを使用してウェブワーカーとしてインポートできます。

js
// Separate chunk in the production build
import 
Worker
from './shader.js?worker'
const
worker
= new
Worker
()
js
// sharedworker
import 
SharedWorker
from './shader.js?sharedworker'
const
sharedWorker
= new
SharedWorker
()
js
// Inlined as base64 strings
import 
InlineWorker
from './shader.js?worker&inline'

詳細については、ウェブワーカーセクションをご覧ください。

public ディレクトリ

次のようなアセットがある場合

  • ソースコードで決して参照されない (例: robots.txt)
  • 全く同じファイル名を維持する必要がある (ハッシュ化なし)
  • ...または単にその URL を取得するためだけにアセットを最初にインポートしたくない場合

その場合、アセットをプロジェクトルートの下の特別な public ディレクトリに配置できます。このディレクトリのアセットは、開発中はルートパス / で提供され、そのまま dist ディレクトリのルートにコピーされます。

ディレクトリはデフォルトで <root>/public ですが、publicDir オプションで設定できます。

public アセットは常にルート絶対パスを使用して参照する必要があることに注意してください。例えば、public/icon.png はソースコードで /icon.png として参照する必要があります。

new URL(url, import.meta.url)

import.meta.url は、現在のモジュールの URL を公開するネイティブ ESM 機能です。これをネイティブの URL コンストラクタと組み合わせることで、JavaScript モジュールから相対パスを使用して静的アセットの完全な解決済み URL を取得できます。

js
const imgUrl = new URL('./img.png', import.meta.url).href

document.getElementById('hero-img').src = imgUrl

これはモダンブラウザでネイティブに動作します。実際、Vite は開発中にこのコードを全く処理する必要はありません!

このパターンは、テンプレートリテラルを介した動的 URL もサポートしています。

js
function getImageUrl(name) {
  // note that this does not include files in subdirectories
  return new URL(`./dir/${name}.png`, import.meta.url).href
}

プロダクションビルド中、Vite は必要な変換を実行し、バンドルとアセットハッシュ化の後でも URL が正しい場所を指すようにします。ただし、URL 文字列は分析できるように静的である必要があります。そうでない場合、コードはそのまま残され、build.targetimport.meta.url をサポートしていない場合、ランタイムエラーが発生する可能性があります。

js
// Vite will not transform this
const imgUrl = new URL(imagePath, import.meta.url).href
仕組み

Vite は getImageUrl 関数を次のように変換します。

js
import __img0png from './dir/img0.png'
import __img1png from './dir/img1.png'

function getImageUrl(name) {
  const modules = {
    './dir/img0.png': __img0png,
    './dir/img1.png': __img1png,
  }
  return new URL(modules[`./dir/${name}.png`], import.meta.url).href
}

SSRでは動作しません

Vite をサーバーサイドレンダリングに使用している場合、このパターンは機能しません。なぜなら、import.meta.url はブラウザと Node.js で異なるセマンティクスを持っているからです。また、サーバーバンドルはクライアントホスト URL を事前に決定できません。

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