pkg を活用した AWS Lambda 向け Node.js アプリケーションのパッケージング手法

AWS Lambda で Node.js アプリケーションを実行する際、依存関係を含めたパッケージングはデプロイの成否を左右する重要な工程です。pkg(Vercel 製)は Node.js プロジェクトを単一の実行可能ファイルに変換し、ランタイム環境の差異を吸収しながら、コールドスタートやパッケージサイズの課題を解決します。本記事では、pkg を用いて Lambda 関数向けに最適化されたパッケージを作成する手順を詳しく解説します。

pkg が AWS Lambda にもたらす利点

  • コールドスタートの短縮: 動的ロードが不要なため、起動時間が平均 30% 以上改善されます。
  • デプロイパッケージの小型化: 不要なファイルを自動除外し、サイズを 40~60% 削減できます。
  • 環境の再現性: バイナリに Node.js ランタイムが組み込まれるため、Lambda 環境との整合性が保たれます。

pkg を用いた Lambda 向けパッケージングの実践

1. ツールのインストール

npm install -g pkg
# またはプロジェクトローカルに
npm install pkg --save-dev

2. package.json の設定

エントリポイントとターゲットプラットフォームを指定します。

{
  "name": "lambda-function",
  "main": "handler.js",
  "pkg": {
    "scripts": "handler.js",
    "assets": ["config/*.json"],
    "targets": ["node18-linux-x64"]
  }
}

3. 実行可能ファイルの生成

pkg . --targets node18-linux-x64 --output bootstrap

生成された bootstrap ファイルが Lambda のカスタムランタイムエントリポイントとして動作します。

4. デプロイパッケージの作成

mkdir deploy
cp bootstrap deploy/
zip -j deploy/function.zip deploy/bootstrap

パフォーマンス最適化のための追加設定

依存関係の除外

{
  "pkg": {
    "exclude": ["aws-sdk", "sharp"]
  }
}

aws-sdk は Lambda 環境にプリインストールされているため、除外してサイズを削減できます。

アセットのバンドル

{
  "pkg": {
    "assets": ["views/**/*.ejs", "public/**/*"]
  }
}

テンプレートや静的ファイルを明示的に含めます。

動的 require への対応

{
  "pkg": {
    "scripts": "src/**/*.js"
  }
}

動的にロードされるモジュールは事前に指定しておく必要があります。

トラブルシューティング

  • ネイティブモジュエルのエラー: --no-bytecode オプションを試すか、ビルド環境を Lambda の Amazon Linux 2 に合わせてください。
  • パス問題: __dirname の参照先が変わるため、絶対パスを使用してください。

デプロイと検証

aws lambda update-function-code --function-name my-function --zip-file fileb://deploy/function.zip
aws lambda invoke --function-name my-function --payload '{}' output.txt

まとめ

pkg によるパッケージングは、Node.js アプリケーションを Lambda にデプロイする際の標準的な手法として定着しつつあります。適切な設定と最適化を施すことで、軽量で高速なサーバーレスアプリケーションを構築できます。Lambda 関数のパフォーマンス向上を目指す場合は、ぜひ導入を検討してみてください。

タグ: pkg AWS Lambda Node.js サーバーレス デプロイ

7月20日 16:09 投稿