vite: Assets with a dynamic URL are ignored
Is your feature request related to a problem? Please describe.
When something like <img src=example.png> is used in a Vue template, vite build handles it by copying the PNG file into the dist directory with a hash in the filename etc. However this doesn’t happen when the image filename is dynamic. For example:
<ul>
<li v-for="item in items">
<img v-bind:src="`icons/${item.slug}.png`" />
{{ item.name }}
</li>
</ul>
The src attribute in the browser’s DOM are exactly the result of template interpolation, which works out with Vite’s own development server but not in “production” since image files are missing.
Describe the solution you’d like
I sort of understand why this doesn’t Just Work, but it’d be nice if it did. Alternatively, is there some other ways to tell Vite about which images exist? The value of item.slug is always in some finite set, although there are more of them that I’d rather hard-code in a template. Or, am I doing something very wrong and shouldn’t use reactive data for this? I’m very new to Vue.
Describe alternatives you’ve considered
Moving these images to the public directory would probably work, but Vite’s README describes this as an escape hatch that is best avoided.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 13
- Comments: 24
As mentioned in https://github.com/vitejs/vite/issues/1265#issuecomment-757450141, I tried using
globlikeconst images = import.meta.globEager("/src/images/*.png");. It wasn’t working at first, then I realized that you need to use.defaultlikeimages["/src/images/image.png"].default.Just FYI for any one else trying to use globs with static assets.
Based on @amir20 I ended up doing something like this:
Then in any file:
This way you can keep all your assets in one place and avoid magic strings. It’s a little bit more work to add each asset in the composable return, but in the long run it’s quite nice,
@SimonSapin
After
vite 2.0.0-beta.17you can try glob-import to import all resources at once.Did you chose
globEager()instead ofglob()on purpose? If I understood the Vite docs correctlyglobEager()imports all assets directly (no lazy-loading). Depending on the number of assets this could have a performance impact.Here is an example using
glob()if you want to lazy-load an asset based on a prop in your component.Would this be a good way to handle it or is there a more simple or straightforward way of solving this?
vite 引入图片资源 html:
script:
import on from ‘@/assets/voice.png’ import off from ‘@/assets/no_voice.png’
const state = reactive({ voiceSrc: off })