コンテンツにスキップ

静的アセットの取り扱い

アセットを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のインライン化

JSによって手動で構築された 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 サフィックスを使用してWebワーカーとしてインポートできます。

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'

詳細は、Webワーカーのセクション を確認してください。

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ライセンスでリリースされています。(ccee3d7c)