Vercel部署svg2img转PNG服务报ERR_REQUIRE_ESM错误如何解决?
问题成因
- 你使用的
svg2img@0.9.3本身是CommonJS规范的包,内部使用require()语法加载依赖canvg canvg从v4版本开始已经升级为纯ESM模块,它的package.json中包含"type": "module"配置,Node.js不允许CommonJS模块用require()直接加载ESM模块- 本地
vercel dev运行正常通常是因为本地Node版本、依赖缓存的兼容宽松度更高,而Vercel Serverless运行时对模块规范的校验更严格,所以触发了报错。
解决方法
推荐优先使用第一种方案,改造成本最低:
方案1:强制锁定canvg的CommonJS版本
在你的package.json中添加依赖覆盖配置,强制svg2img使用最后一个支持CommonJS的canvg@3.0.10版本:
如果使用npm作为包管理器,新增overrides字段:
{ "name": "svg2png", "version": "1.0.0", "description": "convert svgs to pngs", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "me", "license": "ISC", "dependencies": { "svg2img": "^0.9.3" }, "type": "module", "overrides": { "svg2img": { "canvg": "3.0.10" } } }
如果使用yarn作为包管理器,将overrides替换为resolutions字段即可。
修改完成后删除本地的node_modules和锁文件(package-lock.json/yarn.lock),重新安装依赖后再部署到Vercel即可解决问题。
方案2:替换为ESM兼容的转换库
如果不想锁旧版本依赖,可以替换svg2img为ESM友好、性能更高的@resvg/resvg-js,业务代码修改示例如下:
import { Resvg } from '@resvg/resvg-js'; export default async function(req, res) { const url = req.query.url; const width = Number(req.query.width); const height = Number(req.query.height); const size = Math.min(width, height); // 先拉取SVG文件内容 const svgResponse = await fetch(url); const svgText = await svgResponse.text(); const resvg = new Resvg(svgText, { fitTo: { mode: 'width', value: size } }); const pngData = resvg.render(); const pngBuffer = pngData.asPng(); res.setHeader('Content-Type', 'image/png'); res.send(pngBuffer); };
修改后同步把package.json中的依赖替换为@resvg/resvg-js即可。
内容的提问来源于stack exchange,提问作者keegan3d
相关产品推荐
相关产品推荐

