chartjs-node-canvasで動的OGP画像を生成する関数をVercelにデプロイするのに苦労した話

とあるサービスの開発をしているとchart.jsで生成したグラフをOGP画像にする必要が出て、Vercelならサーバレス関数を無料でデプロイできると知り試したのですが、謎のエラーが発生して困っていました。
その回避策(？)をとりあえず見つけたのでメモ書き程度に書きます。

# version

canvas: 2.6.1
chartjs-node-canvas: ^3.2.0
chart.js: ^3.5.0

# 発生してたエラー

```
ERROR	Unhandled Promise Rejection 
{
"errorType":"Runtime.UnhandledPromiseRejection",
"errorMessage":"Error: Cannot find module 'canvas'\n
Require stack:\n
- /var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js\n
- - /var/task/node_modules/chartjs-node-canvas/dist/legacy.js\n
- - /var/task/node_modules/chartjs-node-canvas/dist/index.js\n
- -  /var/task/api/index.js","reason":{"errorType":"Error","errorMessage":"Cannot find module 'canvas'\n
- Require stack:\n- /var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js\n
- - /var/task/node_modules/chartjs-node-canvas/dist/legacy.js\n
- - /var/task/node_modules/chartjs-node-canvas/dist/index.js\n
- - /var/task/api/index.js",
- "code":"MODULE_NOT_FOUND",
- "requireStack":[
- "/var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js",
- "/var/task/node_modules/chartjs-node-canvas/dist/legacy.js",
- "/var/task/node_modules/chartjs-node-canvas/dist/index.js",
- "/var/task/api/index.js"],
- "stack":[
- "Error: Cannot find module 'canvas'","Require stack:",
- "- /var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js",
- "- /var/task/node_modules/chartjs-node-canvas/dist/legacy.js",
- "- /var/task/node_modules/chartjs-node-canvas/dist/index.js",
- "- /var/task/api/index.js",
- "    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)",
- "    at Function.resolve (internal/modules/cjs/helpers.js:98:19)",
- "    at Object.exports.freshRequire (/var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js:6:34)",
- "    at new ChartJSNodeCanvas (/var/task/node_modules/chartjs-node-canvas/dist/new.js:23:39)",
- "    at module.exports (/var/task/api/index.js:14:31)",
- "    at Server.<anonymous> (/var/task/___vc/__helpers.js:813:19)",
- "    at Server.emit (events.js:375:28)",
- "    at parserOnIncoming (_http_server.js:897:12)",
- "    at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: Error: Cannot find module 'canvas'",
- "Require stack:",
- "- /var/task/node_modules/chartjs-node-canvas/dist/freshRequire.js",
- "- /var/task/node_modules/chartjs-node-canvas/dist/legacy.js",
- "- /var/task/node_modules/chartjs-node-canvas/dist/index.js",
- "- /var/task/api/index.js",
- "    at process.<anonymous> (/var/runtime/index.js:35:15)",
- "    at process.emit (events.js:387:35)",
- "    at processPromiseRejections (internal/process/promises.js:245:33)",
- "    at processTicksAndRejections (internal/process/task_queues.js:96:32)"]}
Unknown application error occurred
```

もちろんcanvasモジュールはpacakge.jsonに記述されていましたが、存在しないと言われてしまいました。

# 回避策

次のrequire('canvas')を加える(使わなくても必要)

```js
const { ChartJSNodeCanvas } = require('chartjs-node-canvas');
const canvas = require('canvas'); // ポイント
```

package.jsonのvercel-buildを設定する。

```json
"scripts": {
      "vercel-build": "yum install libuuid-devel libmount-devel && cp /lib64/{libuuid,libmount,libblkid}.so.1 node_modules/canvas/build/Release/"
    }
```

これだけでグラフは表示されましたが、文字が表示されなかったのでフォントの登録が必要です。
フォントの登録はREADMEに書いてあった`ChartJS.defaults.global.defaultFontFamily`では動かなかったので、chart.jsの公式ドキュメントを確認して`ChartJS.defaults.font.family`にしました。

サンプルレポジトリ
https://github.com/karintou8710/vercel-chartjs-node-canvas

# なぜこれで動いたの？

全くわからないです...
エラーメッセージに書いてある/var/task/node_moduleの中身を**require('canvas')**を加えない場合と比較したところ、加えない場合はcanvasとその依存関係にあるモジュールがインストールされていませんでした。
vercelの最適化が関係しているのか？と最初は考えたのですが、そもそもpackage.jsonに書いてあるのにインストールされないのは不思議です。
もし理由が分かる方がいればぜひコメントで教えて頂きたいです。