nextjs + sharp在 vercel 环境svg转png出现中文乱码
2023-12-20 17:22:33
    		在之前一篇博客 Next.js和sharp实现占位图片生成工具,详细介绍了使用 Next.js  + sharp + Vercel 来实现一个 占位图片生成工具,遇到一个奇怪的问题:在本地开发环境,英文、数字、中文字符自定义内容,都能正常渲染。但是发布到 Vercel 生产环境,自定义内容除了英文字符和数字外,中文字符 显示为 Unicode 码位(乱码),如下图所示。

问题原因
经过排查,发现是 sharp 库在 vercel 生产环境下,对 svg 转 png 时,中文字符 会出现乱码。而在本地开发环境,sharp 库对 svg 转 png 时,中文字符 不会出现乱码。
 在 vercel 平台查看 log 日志,发现了错误提示:Fontconfig error: No writable cache directories。
 进一步定位,说明是 vercel 容器环境没有支持中文的字体,因此无法正常渲染中文字符。
解决方案
- 在 nextjs项目根目录下,创建fonts文件夹,将中文字体文件NotoSansSC-Regular.ttf放入fonts文件夹中。我这里使用的是NotoSansSC-Regular.ttf字体,支持简体中文字符。下载地址:https://github.com/notofonts/noto-cjk
- 在 fonts文件夹下,创建fonts.conf文件,内容如下:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/var/task/fonts/</dir>
  <cachedir>/tmp/fonts-cache/</cachedir>
  <config></config>
</fontconfig>
- 在 sharp处理svg转png函数所在文件的头部加入如下代码:
resolve(process.cwd(), 'fonts', 'fonts.conf')
resolve(process.cwd(), 'fonts', 'NotoSansSC-Regular.ttf')
- 在项目根目录下创建一个 .env环境变量文件,内容如下:
FONTCONFIG_PATH=/var/task/fonts
- 在 svg中设置font-family,如下:
function getSvgBuffer({ w, h, bg, color, size, text }) {
  let textY = (+h + size / 2) / 2
  let svg = `
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs"
    width="${w}" height="${h}">
    <rect width="${w}" height="${h}"
    fill="${bg}" style="fill:${bg};"/>
    <text x="50%" y="${textY}" 
    style="font-family: 'Noto Sans', 'Noto Sans SC', sans-serif;"
    dominant-baseline="alphabetic" text-anchor="middle" 
    stroke="none" stroke-width="0" 
    font-size="${size}" fill="${color}" 
    fill-opacity="1">${text}</text>
</svg>`
  svg = '<?xml version="1.0" encoding="UTF-8"?>' + svg
  return Buffer.from(svg, 'utf-8')
}
- 在 vercel平台上配置环境变量FONTCONFIG_PATH,值为/var/task/fonts。

- 再次发布到 vercel平台,问题解决。
参考文档:
- https://sharp.pixelplumbing.com/install#fonts
- https://github.com/lovell/sharp/issues/3698
- https://github.com/lovell/sharp/issues/1875
欢迎访问:天问博客
    			文章来源:https://blog.csdn.net/tiven_/article/details/135107061
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!