Resemble.jsがサーバーサイドで上手く動作しなかった話

概要

Next.js + Prisma環境で、サーバーサイドでResemble.jsが動作せず苦労したのでメモ。

環境

  • Node: 16
  • Next.js: 12.1.6
  • Prisma: 3.15.1
  • Resemble.js: 4.1.0
  • TypeScript

エラーその1

no such file or directory canvas

これは分かりやすい。
node_modules を見るとcanvasがインストールされていないようなので、インストールする。

yarn add canvas

エラーその2

Error: Cannot find module '../build/Release/canvas.node'

このエラーに大変悩まされたが、node-canvasのリポジトリ(https://github.com/Automattic/node-canvas#compiling) に解決策が記載されていた。

まず、Resemble.jsはnode-canvas を利用している。
node-canvasとは、CairoをフレームとするNode.js用Canvas実装。
Cairoはデバイスに依存しないベクトルベースの描画APIを提供する、フリーの2Dグラフィックスライブラリ (Wikipedia調べ)。

node-canvasはサポートされているOSまたはプロセッサアーキテクチャがない場合、システム上でコンパイルされる。今回の場合、yarn add 時にコンパイルされると思われるが、この時システム上にいくつかの依存関係が必要。

本来であれば yarn add 時にコンパイルエラーがある場合はそこでインストールが止まると思われるが、node_modules/package.json を見ると

"optionalDependencies": {
    "canvas": "2.9.0"
},

となっていた。
optionalDependencies に指定されている場合、利用可能であればインストールされるが、利用不可であっても他の処理は止まらず継続される。
よくよくログを見ると、

npm ERR! node-pre-gyp info it worked if it ends with ok
npm ERR! node-pre-gyp info using node-pre-gyp@1.0.6

みたいなエラーが大量に出ていた。

対策としては、上記リンクにあるようにOSごとに必要な依存関係をインストールしてから yarn add する。

MacOSであれば、

brew install pkg-config cairo pango libpng jpeg giflib librsvg

その後

yarn add canvas

以上でResemble.jsがサーバーサイドで正常動作するようになる🙌