如何在Vercel Edge的SvelteKit中正确导入初始化@resvg/resvg-wasm?
在Vercel Edge环境的SvelteKit中正确使用@resvg/resvg-wasm的解决方案
问题描述
在Vercel Edge环境的SvelteKit项目中使用@resvg/resvg-wasm模块时,本地运行正常,但部署后出现以下错误:
CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder at (../../../../../node_modules/@resvg/resvg-wasm/index.mjs:425:29) at (../../../../../node_modules/@resvg/resvg-wasm/index.mjs:541:31) at (../../../../../node_modules/@resvg/resvg-wasm/index.mjs:552:2) at (../../../../../.svelte-kit/output/server/entries/endpoints/og/_server.ts.js:14:6) at (../../../../../.svelte-kit/output/server/entries/endpoints/og/_server.ts.js:55:23)
尝试过直接导入包内的.wasm文件(@resvg/resvg-wasm/index_bg.wasm?inline)和本地复制.wasm文件导入,均未解决问题。注意到@vercel/og使用相同模块却能正常运行,但代码不开源。
解决方案
1. 确保依赖版本兼容
安装最新稳定版的@resvg/resvg-wasm,保证其支持Edge环境:
npm install @resvg/resvg-wasm@latest
2. 改用异步方式加载与初始化Wasm
Vercel Edge Runtime禁止同步编译Wasm,必须使用异步加载逻辑。创建一个工具函数封装初始化流程:
// src/lib/resvg.ts import type { InitInput } from '@resvg/resvg-wasm'; import { initWasm, Resvg } from '@resvg/resvg-wasm'; // 避免重复初始化 let wasmInitialized = false; async function initResvg() { if (wasmInitialized) return; // 异步fetch加载Wasm文件 const response = await fetch(new URL('@resvg/resvg-wasm/index_bg.wasm', import.meta.url)); const bytes = await response.arrayBuffer(); await initWasm(bytes as InitInput); wasmInitialized = true; } // 封装SVG转PNG的函数 export async function renderSvgToPng(svg: string) { await initResvg(); const resvg = new Resvg(svg); const pngData = resvg.render(); return pngData.asPng(); }
3. 配置Edge端点
确保你的SvelteKit端点明确指定运行时为edge:
// src/routes/og/+server.ts import type { RequestHandler } from './$types'; import { renderSvgToPng } from '$lib/resvg'; // 指定使用Edge Runtime export const config = { runtime: 'edge', }; export const GET: RequestHandler = async ({ url }) => { // 示例SVG内容,可根据需求动态生成 const svg = `<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"><text x="50" y="100" font-size="24">Hello Edge OG Image</text></svg>`; const pngBuffer = await renderSvgToPng(svg); return new Response(pngBuffer, { headers: { 'Content-Type': 'image/png', 'Cache-Control': 'public, max-age=31536000', }, }); };
4. 可选:调整Vite打包配置
如果遇到Wasm文件打包异常,在vite.config.ts中添加优化配置:
import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [sveltekit()], optimizeDeps: { // 避免Vite预构建该模块,保留原始加载逻辑 exclude: ['@resvg/resvg-wasm'], }, });
关键原理
Vercel Edge Runtime限制了同步WebAssembly代码生成,因此必须通过异步fetch加载Wasm文件并初始化,这也是@vercel/og内部的适配逻辑。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

