Svelte 5非SvelteKit项目JSON动态图片路径构建后失效问题
Svelte 5(非SvelteKit)动态图片路径构建问题解决方案
问题根源
开发模式下Vite会直接代理访问src/lib下的文件,但构建后所有资源会被打包到dist目录,JSON里的硬编码路径不会被Vite自动转换,导致图片无法访问。必须通过显式方式让Vite识别这些动态资源。
方案1:批量导入+路径映射
适合图片数量固定的场景,一次性导入所有图片后匹配替换路径:
1. 修改JSON中的路径
把data.json里的图片路径改成文件名(或相对JSON的短路径),避免硬编码绝对路径:
[ { "title": "tile 1", "images": [ { "src": "tile1a.jpg" }, { "src": "tile1b.jpg" } ] }, { "title": "tile 2", "images": [ { "src": "tile2a.jpg" }, { "src": "tile2b.jpg" } ] } ]
2. 父组件中批量导入并处理数据
用Vite的import.meta.glob批量导入所有图片,再把JSON里的文件名映射成构建后的正确URL:
<script lang="ts"> import data from "$lib/data.json"; import ChildComponent from "$lib/components/ChildComponent.svelte"; // 批量导入src/lib/images下的所有jpg图片,eager设为true表示立即加载,as:url返回资源URL const imageAssets = import.meta.glob("/src/lib/images/*.jpg", { eager: true, as: "url" }); // 处理数据,替换图片路径 const processedData = data.map(tile => ({ ...tile, images: tile.images.map(img => { // 拼接完整路径匹配导入的资源 const fullPath = `/src/lib/images/${img.src}`; return { src: imageAssets[fullPath] as string }; }) })); </script> <main> {#each processedData as tile} <ChildComponent title={tile.title} images={tile.images} /> {/each} </main>
方案2:用new URL()动态解析路径
如果图片数量不固定,或者不想批量导入,可以在子组件中用new URL()让Vite识别资源:
1. 调整JSON路径
同样把JSON里的路径简化为文件名:
[ { "title": "tile 1", "images": [ { "src": "tile1a.jpg" }, { "src": "tile1b.jpg" } ] } ]
2. 子组件中处理路径
在子组件里通过new URL()生成正确的资源URL,Vite构建时会自动处理这些路径:
<script lang="ts"> interface Props { title: string; images: { src: string }[]; } const { title, images }: Props = $props(); // 生成构建后的图片URL const getImageUrl = (fileName: string) => { // 第一个参数是相对于当前组件的图片路径,第二个参数是当前组件的URL return new URL(`../lib/images/${fileName}`, import.meta.url).href; }; </script> <div class="tile"> <span>{title}</span> {#each images as i} <img src={getImageUrl(i.src)} /> {/each} </div>
注意事项
- 两种方案都要确保JSON里的路径和实际图片文件名完全匹配,大小写也要一致
- 不要在路径里用
/src/lib这种绝对路径,构建后这个目录不会存在于dist中
内容的提问来源于stack exchange,提问作者bolino
相关产品推荐
相关产品推荐

