When building projects with Vue3 and Vite, static image resources usually display correctly in both development and production environments. However, when attempting to use dynamically generated image resources (such as loading image names from a database), a problem may occur where the images display correctly in the development environment but fail to show in the production environment. This article will delve into the manifestation and cause of this problem in detail and provide corresponding solutions.

Problem Description

In a Vue3 project combined with Vite, static image sources work properly in both development and production environments. However, the situation is different for dynamically generated image sources.

Phenomenon

Dynamically generated image sources can display images correctly in the development environment, but in the production environment after Vite builds, the images will show a 404 error. This is because Vite can correctly handle the paths of static images during the build process, but it cannot correctly handle the combined paths of dynamic images.

Example of Error Code

<template>
<!--Dynamically combined img src will cause problems in the production environment -->
<img :src="'/src/assets/images/' + menuItem.iconSource" />
</template>

Cause Analysis

Vite does not process the dynamically combined img src paths during the production build. It treats the path prefix as a constant. However, the actual location of the resources changes after the build (the resources are placed in the _assets folder), which leads to the 404 error for images in the production environment. Additionally, due to the limitations of Rollup, there are restrictions on imports in Vite when they start with a variable.

Solutions

1. Static URL Method

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
import imageUrl from "@/assets/images/logo.svg";
</script>

2. Dynamic URL with Relative Path Method

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
const imageUrl = new URL(`./dir/${name}.png`, import.meta.url).href;
</script>

3. Dynamic URL with Absolute Path, Using Computed Property Method

<template>
<img :src="imageUrl" />
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({ name: String });
const imageUrl = computed(() => new URL(`@/assets/images/${props.name}.png`, import.meta.url).href);
</script>

4. Dynamic URL with Absolute Path (Replacing @/ with /src) Method

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
const imageUrl = new URL("/src/assets/images/logo.svg", import.meta.url);
</script>

Another Example of Using a Computed Property to Handle Dynamic Paths

var imagePath = computed(() => {
switch (condition.value) {
case 1:
const imgUrl = new URL("../assets/1.jpg", import.meta.url);
return imgUrl;
break;
case 2:
const imgUrl2 = new URL("../assets/2.jpg", import.meta.url);
return imgUrl2;
break;
case 3:
const imgUrl3 = new URL("../assets/3.jpg", import.meta.url);
return imgUrl3;
break;
}
});

Conclusion

When dealing with dynamic image sources in a Vue3 Vite project, pay attention to the differences in how Vite builds handle static and dynamic paths. You can choose an appropriate solution according to your specific needs, such as using static URLs, combining dynamic URLs with relative or absolute paths, and leveraging computed properties to handle dynamic paths, so as to avoid the problem of 404 errors for images in the production environment.