引入含原生模块的resvg库导致Vite构建失败如何解决?
解决 SvelteKit + @resvg/resvg-js 构建失败问题
问题根源
Rollup 在构建时尝试打包 @resvg/resvg-js 内部的二进制 .node 文件(如 resvgjs.win32-x64-msvc.node),但 Rollup 无法处理非 JavaScript 文件,导致出现 Unexpected character '�' 错误。开发环境正常是因为 Vite 不会对原生模块进行打包处理。
解决方案
方案一:调整 Vite/Rollup 配置,排除原生模块
修改你的 vite.config.js,确保 Rollup 将原生模块标记为外部依赖,不进行打包:
import { sveltekit } from "@sveltejs/kit/vite"; import { defineConfig } from "vite"; import fs from "fs"; function rawFonts(ext: any[]) { return { name: "vite-plugin-raw-fonts", transform(code: any, id: any) { if (ext.some((e) => id.endsWith(e))) { const buffer = fs.readFileSync(id); return { code: `export default ${JSON.stringify(buffer)}`, map: null }; } }, }; }; export default defineConfig({ plugins: [ sveltekit(), rawFonts([".ttf"]), ], // 告诉 Vite 不要优化 resvg 依赖 optimizeDeps: { exclude: ["fsevents", "@resvg/resvg-js"] }, build: { rollupOptions: { // 将 resvg 及其原生模块标记为外部依赖 external: [ '@resvg/resvg-js', // 排除所有 .node 原生文件 (id) => id.endsWith('.node') ], }, }, });
方案二:使用动态导入(备选)
如果上述配置仍不生效,可以在代码中动态导入 @resvg/resvg-js,避免 Rollup 在构建时解析原生模块:
// 替换静态导入为动态导入 async function generatePngFromSvg(svgContent: string) { const { Resvg } = await import('@resvg/resvg-js'); const resvg = new Resvg(svgContent); const pngBuffer = resvg.render().asPng(); return pngBuffer; }
额外注意事项
- 确保使用最新版本的
@resvg/resvg-js、@sveltejs/kit和@sveltejs/adapter-node,避免版本兼容问题。 - 部署时,确保目标环境安装了对应平台的原生模块(例如 Linux 环境需要
resvgjs.linux-x64-gnu.node),可以通过在部署机器上重新运行npm install来自动安装对应平台的版本。
内容的提问来源于stack exchange,提问作者R3FL3CT
相关产品推荐
相关产品推荐

