node-canvas部署至Heroku/Techstar后自定义字体加载失败求助
Node-Canvas 自定义字体部署后加载失败的解决方案
排查与修复步骤
- 修正路径计算逻辑
本地依赖__dirname的多层相对路径(./../../../)在部署后极易因目录结构变化失效,建议将字体统一放置在项目根目录的fonts文件夹下,改用path.resolve()生成基于项目根的绝对路径,例如path.resolve(__dirname, '../fonts/BlockHead_bold.ttf')(根据你的项目目录层级调整)。部署后可通过打印路径日志或在主机上查看文件是否存在,验证路径正确性。 - 改用Buffer加载字体文件
直接读取字体文件为Buffer后注册,彻底绕开路径解析问题:const fs = require('fs'); const path = require('path'); const { registerFont } = require('canvas'); // 读取字体文件为Buffer const blockHeadFont = fs.readFileSync(path.resolve(__dirname, './../../../BlockHead_bold.ttf')); const franchiseFont = fs.readFileSync(path.resolve(__dirname, './../../../Franchise-Free-Bold.ttf')); const mangoldFont = fs.readFileSync(path.resolve(__dirname, './../../../MANGOLD.ttf')); // 注册Buffer格式的字体 registerFont(blockHeadFont, { family: 'BlockHead' }); registerFont(franchiseFont, { family: 'Franchise Free' }); registerFont(mangoldFont, { family: 'MANGOLD' }); - 检查并修复主机文件权限
部署后的字体文件可能因权限不足导致Node进程无法读取,在主机上执行chmod 644 /实际项目路径/fonts/*.ttf,赋予文件可读权限。 - 选择适配的主机平台
放弃Heroku后,优先选择DigitalOcean App Platform、Render这类平台,它们默认预装了node-canvas依赖的cairo等组件,无需额外配置buildpack。部署时务必保证package.json中node-canvas的版本与本地开发环境完全一致,避免版本兼容问题。 - 严格指定渲染字体名称
绘制文本时,对包含空格的字体名称添加双引号,例如ctx.font = '24px "Franchise Free"',确保渲染引擎精准匹配你注册的自定义字体,而非 fallback 到系统默认字体。
内容的提问来源于stack exchange,提问作者kayas
相关产品推荐
相关产品推荐

