Vue3에서부터는 webpack 대신 vite를 사용함에 따라 몇 가지 바뀐 점들이 있는데요. 그 중 제가 가장 와닿았던 건 assets에 있는 이미지를 동적으로 불러와야할 때였습니다. require
를 사용해야하는데 사용할 수가 없게 되었거든요. 그래서 vue3에서는 어떻게 동적으로 이미지를 불러올 수 있는지 알아보았고 그 방법을 공유하고자 합니다.
기존 방법 (Webpack)
name
이라는 변수에 따라 다른 이미지를 불러오고 싶을 때 require
와 조합해서 src 속성에 넣어줬었습니다.
<template>
<img :src="require(`@/assets/images/${name}.png`)" />
</template>
해당 폴더에 Vue.png
라는 파일이 있다면 name 값도 Vue
로 해서 넣어줬을 때 이미지를 불러오고 불러온 이미지 path 값까지 같이 들어갔었습니다.
<img src="/_nuxt/assets/images/Vue.png">
vite에서 이미지를 불러오는 방법
정적으로 불러오는 방법
동적으로 부르지만 않는다면 이미지를 불러오는 방법은 기존과 크게 달라지지 않습니다.
<template>
<img src="@/assets/images/Vue.png" />
</template>
하지만 저희가 원하는 것은 동적으로 부르는 방법이죠. Vite에서는 다음과 같은 방법을 권하고 있습니다.
<script setup>
import { ref } from "vue";
const fname = ref("Vue");
function getImageUrl(name) {
return new URL(`/src/assets/images/${name}.png`, import.meta.url).href;
}
</script>
<template>
<img :src="getImageUrl(fname)" />
</template>
폴더에 있는 모든 이미지 불러오기
한 이미지만 동적으로 가져오는 것이 아니라 특정 폴더 내에 모든 이미지를 긁어와서 표시하고 싶다면, import.meta.glob
을 사용하면 됩니다.
<script setup>
const modules = import.meta.glob("/src/assets/images/*.png", { eager: true });
const images = [];
for (const img in modules) {
images.push(modules[img].default);
}
</script>
<template>
<img :src="img" v-for="img of images" :key="img" />
</template>
SSR 에서 사용하지 마세요.
하지만 이 방법은 SSR에서 먹히지 않습니다. 다음과 같은 에러를 만나시게 될겁니다.

vite 공식 홈페이지에서는 다음과 같이 설명하고 있습니다.
Does not work with SSR
정리하자면 브라우저와 Node.js에서의 image.meta.url 값이 달라질 뿐만 아니라 서버 입장에서도 클라이언트 호스트의 URL을 미리 결정할 수 없기 때문에 assets의 리소스 위치를 구할 수 없다는 뜻으로 보입니다.
그래서 assets 대신 public 폴더에 이미지를 넣는다면 해결됩니다. public 폴더에 Vue.png
를 넣고 다음과 같이 불러오면 잘 됩니다.
<!-- name = "Vue" -->
<img :src="`/${name}.png`" />