AWS Lambda Node环境下FabricJS生成Data URI图片自定义字体不生效
问题:AWS Lambda运行Node后端调用FabricJS生成图片时自定义字体不生效
在AWS Lambda环境中运行Node后端,基于FabricJS画布生成图片,除画布中文本框的fontFamily属性不生效外,其余功能运行正常。
目录结构
字体文件存放在src目录下的fonts文件夹中,结构如下:
src |----fonts |----fabric.conf |----Source |----SourceSansPro-Regular.otf |----SourceSansPro-Semibold.otf
已完成配置
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>
环境变量配置
FONTCONFIG_PATH="/var/task/fonts" FONTCONFIG_FILE="/var/task/fonts/fonts.conf"
核心代码
字体注册与画布逻辑
const { fabric } = require('fabric') fabric.nodeCanvas.registerFont('fonts/Source/SourceSansPro-Regular.otf', {family: 'Source Sans Pro'}) fabric.nodeCanvas.registerFont('fonts/Source/SourceSansPro-Semibold.otf', {family: 'Source Sans Pro Semibold'}) const canvas = new fabric.Canvas('canvas', {}) canvas.loadFromJSON(canvasJson, async () => { ... canvas.renderAll() const dataURL = canvas.toDataURL({ width: canvas.width, height: canvas.height, left: 0, top: 0, format: 'png' }) console.log(dataURL) })
画布JSON配置片段
"objects": [ ... { "shadow": null, ... "type": "textbox", ... "fontFamily": "Source Sans Pro Semibold", ... }, ... ]
现象
最终导出的图片中仅显示默认字体,指定自定义字体未生效:

解决方案
1. 修正字体注册路径
AWS Lambda部署后代码运行根目录为/var/task,相对路径容易因工作目录偏移找不到字体文件,改为绝对路径注册:
const path = require('path') // 按你实际代码目录层级调整路径拼接规则 fabric.nodeCanvas.registerFont(path.resolve(__dirname, './fonts/Source/SourceSansPro-Regular.otf'), {family: 'Source Sans Pro'}) fabric.nodeCanvas.registerFont(path.resolve(__dirname, './fonts/Source/SourceSansPro-Semibold.otf'), {family: 'Source Sans Pro Semibold'})
2. 强制刷新文本对象样式
FabricJS加载JSON时可能存在样式缓存未更新的问题,加载完成后遍历所有文本对象标记重绘:
canvas.loadFromJSON(canvasJson, async () => { // 遍历所有文本类对象强制更新 canvas.getObjects().forEach(obj => { if (['text', 'textbox', 'itext'].includes(obj.type)) { obj.dirty = true } }) canvas.renderAll() // 后续导出逻辑不变 })
3. 排查打包配置
确认项目打包工具(Webpack/ESbuild等)配置了静态资源拷贝规则,完整将fonts目录拷贝到部署包对应路径下,避免部署后字体文件丢失。
4. 清理fontconfig缓存
Lambda冷启动阶段先清理旧的字体缓存,避免缓存导致的字体加载失败:
const fs = require('fs/promises') await fs.rm('/tmp/fonts-cache', { recursive: true, force: true }) await fs.mkdir('/tmp/fonts-cache', { recursive: true })
内容的提问来源于stack exchange,提问作者Alien13
相关产品推荐
相关产品推荐

