Node.js初心者の自分が以下の先輩の記事を読み、「Puppeteer on Lambdaをやってみたい!」と思って試したところ、Lambdaにデプロイする前にハマったので解決法を紹介します。
前提
- Node.jsとnpmがインストールされている
- Node.jsのバージョンはv8.10.0である
下記のコマンドでバージョンをチェックします。
$ node -v add
v8.10.0
ディレクトリ構成がわからない
自分はNode.jsのプロジェクトを作成するのが初めてだったので、ディレクトリ構成がわかりませんでした。まずはPuppeteer用のディレクトリを作成し、その中で下記の2ファイルを作りましょう。
├── .npmrc
└── package.json
プロジェクトごとに.npmrcを設定するのがベターです。.npmrcとpackage.jsonの内容は後述します。
.npmrcの設定
Lambda上では、@serverless-chrome/lambda内にあるheadless-chromiumを起動します。このため、Puppeteerで本体とともにインストールされるChroniumは不要です。しかも、インストールしてしまうと、zipで圧縮しても53MB程度になり、Lambda上で50MBのデプロイ制限に引っかかります。
このため、.npmrcにPUPPETEER_SKIP_CHROMIUM_DOWNLOAD=TRUE
を書き込みましょう。すると、後述の $ npm install
時に、ターミナルにこのような記載が出てきます。
**INFO** Skipping Chromium download.
"PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in npm config.
それでもChroniumがインストールされてしまう場合は、puppeteer_skip_chromium_download=true
と小文字にして再トライするとChroniumがインストールされなくなります。
(参考)
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD not respected in NPM Config
package.jsonの設定
@serverless-chrome/lambdaのページに飛ぶと、インストールするには $ npm install --save @serverless-chrome/lambda
を入力すると書いてあります。
しかし、@serverless-chrome/lambdaの最新バージョンは1.0.0-49(2018/6/19時点)です。Puppeteerの最新バージョンは1.5(同上)なので、互換性があるかが不明です。このため、package.jsonでインストールするモジュールとそのバージョンをあらかじめ指定しておきます。
(本来はここを調べて最新版にするのがベストです。しかし、今回は「Puppeteer on LambdaでWebページのキャプチャを撮る」と同様の環境を構築することを目的としているので、パッケージの互換性の調査は省略します)
{
"name": "puppeteer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"zip": "if [ -e app.zip ]; then rm app.zip ; fi && zip -r app.zip *"
},
"author": "pm-kushibiki",
"license": "MIT",
"dependencies": {
"@serverless-chrome/lambda": "1.0.0-38",
"chrome-remote-interface": "0.25.5",
"puppeteer": "1.2.0"
}
}
モジュールをインストールするコマンド
自分がハマったのはここが最大の原因です。@serverless-chrome/lambdaのバージョンに注意はしていました。そこで、$ npm install --save @serverless-chrome/lambda@1.0.0-38
というコマンドを入力していました。すると、@serverless-chrome/lambdaはバージョン1.0.0-38でインストールされるものの、chrome-remote-interfaceとpuppeteerはインストールされません。
package.jsonに記載したモジュールをインストールするには、作成したプロジェクトのディレクトリで$ npm install
を入力するだけでOKです。
$ npm install add
> puppeteer@1.2.0 install /Users/pm-kushibiki/ptech/node_modules/puppeteer
> node install.js
**INFO** Skipping Chromium download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in npm config.
> @serverless-chrome/lambda@1.0.0-38 postinstall /Users/pm-kushibiki/ptech/node_modules/@serverless-chrome/lambda
> node scripts/postinstall.js
Downloading precompiled headless Chromium binary (stable channel) for AWS Lambda.
Completed Headless Chromium download.
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN puppeteer@1.0.0 No description
npm WARN puppeteer@1.0.0 No repository field.
added 44 packages from 27 contributors and audited 78 packages in 93.776s
found 0 vulnerabilities
node_modulesフォルダの中に、@serverless-chrome/lambda、chrome-remote-interface、puppeteerがあれば成功です!
バージョンを確認してみましょう。
$ npm list --depth=0
puppeteer@1.0.0 /Users/pm-kushibiki/ptech
├── @serverless-chrome/lambda@1.0.0-38
├── chrome-remote-interface@0.25.5
└── puppeteer@1.2.0
package.jsonに記載したバージョンと一致していますね!
バージョンの確認とディレクトリ構成のチェック
$ npm install
後、$ touch index.js
でpuppeteerを操作するコードを書くためのindex.jsを作成します。これでディレクトリ構成はこのようになっています。
├── .npmrc
├── index.js
├── node_modules (ここ以下のディレクトリは省略)
├── package-lock.json
└── package.json
index.jsにpuppeteerを動かすコードを書いたあとは、$ npm run zip
でindex.js以下をzip化しましょう。すると、app.zipという名前でzipが作成されます。自分の環境では、43.5MBです。
これでPuppeteer on Lambdaの準備は完了です!Lambdaにはこのapp.zipをアップロードすれば、Lambdaでpuppeteerが使えるようになります!