Vercel Now(旧ZEIT Now)上でnode-canvasを動かす

このサイトでは、記事のサムネイルなんかを作るためにnode-canvasを使用しています。 で、サーバにはVercel Nowを使っています。

node-canvasにはいくつかの共有ライブラリへの依存があるのですが、以下のものはNow上では使用出来ません。

  • libuuid.so
  • libmount.so
  • libblkid.so

なので、何も考えずのnode-canvasをimportしようとすると以下のようなエラーが出てしまいます。

undefined	ERROR	Error: libuuid.so.1: cannot open shared object file: No such file or directory
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:807:18)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/var/task/node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)

しかたがないので、これらを解決してあげる必要があります。

依存関係を解決するためのコマンドは以下のような感じ。 これがnpm run buildする前に動いてくれればOKです。

$ yum install libuuid-devel libmount-devel
$ cp /lib64/{libuuid,libmount,libblkid}.so.1 node_modules/canvas/build/Release/

これを実行してもらうために、package.jsonを以下のように編集します。

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

    // ...そのほか色々...
  }
}

scriptsにnow-buildっていうのを入れておくと、buildの代わりに使ってくれるみたいです。 これを利用して、さきほどのコマンドを実行している感じ。

あとは通常通り、node-canvasが使えるようになっているはずです。


参考: node-canvas runtime error · Issue #3460 · zeit/now