如何在Svelte的+page.server.ts的load()函数中导入图片?
环境与结构
我用Svelte搭建博客,文件夹结构如下:
- posts
- slug1
- banner.webp
- content.md
- ...
- slug1
- src
- blog
- +page.svelte
- +page.server.ts
- [slug]
- +page.svelte
- +page.server.ts
- blog
当前代码
src/blog/[slug]/+page.server.ts中的代码:
import { getPostMetadata, getPostBannerImageURL } from "$lib/blog" import type { PageServerLoad } from './$types'; export const prerender = true; export const load: PageServerLoad = async ({ params }) => { return { slug: params.slug, metadata: getPostMetadata(params.slug), bannerURL: // 待编写的代码 }; };
需求
代码需要支持SSR且可静态编译,要将/posts/${params.slug}/banner.webp加入Vite优化资源列表,并获取正确的展示URL。
尝试的方法及错误
我尝试动态导入图片:
bannerURL: await import(`../../../posts/${params.slug}/banner.webp`)
出现以下错误:
TypeError: Cannot convert object to primitive value at String (<anonymous>) at escape_html (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/chunks/index.js:30:15) at _page (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/entries/pages/blog/_slug_/_page.svelte.js:8:416) at children (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/chunks/internal.js:1155:9) at _layout (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/entries/pages/_layout.svelte.js:202:3) at Root (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/chunks/internal.js:1150:5) at render (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/chunks/index.js:99:3) at Function._render [as render] (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/chunks/internal.js:1112:20) at render_response (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/index.js:1800:34) at async render_page (file:///Users/jlagesse/Documents/GitHub/adrien-lagesse.io/.svelte-kit/output/server/index.js:2627:12)
解决方案
方案1:修正动态导入的取值方式
动态导入图片返回的是模块对象,需要提取default属性才能拿到图片URL:
bannerURL: (await import(`../../../posts/${params.slug}/banner.webp`)).default
方案2:预加载所有Banner资源(推荐)
为了确保Vite能提前扫描并优化所有文章的Banner图片,避免静态编译时遗漏,可按以下步骤操作:
- 在
svelte.config.js中配置Vite识别posts目录下的图片:
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; export default { preprocess: vitePreprocess(), kit: { vite: { assetsInclude: ['posts/**/*.webp'] } } };
- 修改
+page.server.ts,用import.meta.glob预加载所有Banner资源:
import { getPostMetadata } from "$lib/blog" import type { PageServerLoad } from './$types'; export const prerender = true; // 预加载所有posts下的banner图片,eager设为true直接加载 const banners = import.meta.glob('../../../posts/**/banner.webp', { eager: true }); export const load: PageServerLoad = ({ params }) => { const bannerPath = `../../../posts/${params.slug}/banner.webp`; return { slug: params.slug, metadata: getPostMetadata(params.slug), bannerURL: banners[bannerPath]?.default || null }; };
这种方式既支持SSR,又能让Vite提前处理所有Banner资源,静态编译时也能生成正确的资源URL。
内容的提问来源于stack exchange,提问作者Adrien Lagesse
相关产品推荐
相关产品推荐

