🏞️

Nuxt3でassetsの画像を動的に表示する

2022/08/26に公開

TL;DR

import.meta.globEagerを使う。

背景

Nuxt2では、assetsの画像を動的に表示するときは

<img :src="require(hogehoge)">

のようにしていた。
しかし、Nuxt3で使われているViteにはrequireがないため、この方法が使えない。

環境

MacOS 12.3.1
Node 16.16.0
Nuxt 3.0.0-rc.6
Vite 2.9.14

解決方法

src/lib/images.ts
const images = import.meta.globEager?.('../assets/images/**/*') || {}

const ret: Record<string, string> = {}
for (const key in images) {
  ret[key.replace('../assets/images/', '')] = images[key].default
}

export default ret as Readonly<typeof ret>
src/components/base/DynamicImg.vue
<template>
  <img :src="internalSrc">
</template>

<script setup lang="ts">
import images from '@/lib/images'

const props = defineProps({
  src: {
    type: String,
    default: ''
  }
})
const { src } = toRefs(props)

const internalSrc = computed<string | undefined>(() => images[src.value])
</script>

注意点

import.meta.globEagerはVite 3で非推奨になっている。
今回はViteのバージョンが2.9.14だったので問題なかったが、いずれ書き換えなければいけなくなるかもしれない。

うまくいかなかった方法

最初、この記事の通りにやってみた。
https://zenn.dev/one_dock/articles/77cd256c887204

この記事では、新旧2つの方法が紹介されている(2022/08/26現在)。

(1) new URL(...)的なやつ

これ単体では動くのだが、他のモジュールと相性が悪かった。
グローバルにScss変数を使いたかったので、style-resourcesモジュールをNuxt3用に改造して使っていたのだが、なぜかこれと干渉して本番用ビルドができない(nuxi devはできた)。
https://github.com/nuxt-community/style-resources-module

import.meta.urlをコメントアウトして適当な文字列に置き換えるとビルドはできる(もちろん画像のsrcは壊れるが)ので、その辺に問題があるのだろう。たぶん。知らんけど。

(2) vueファイルからの相対パスを渡すやつ

開発環境だとうまくいった。
本番環境では、ビルドは通るが、いざブラウザからアクセスすると壊れていた。

Discussion