AWS LambdaのNode.jsランタイムを16から18にしたらaws-sdkがインポートできなくなった
はじめに
AWSのLambdaで使っているランタイムのNode.js16がサポート終了とのことで、Node.js18にしたところ、動かしていたプログラムが以下のエラーを吐いた。
“Runtime.ImportModuleError: Error: Cannot find module ‘aws-sdk'”
原因
エラー内容からもわかるように、aws-sdkモジュールがインポートできていない。
調べてみると、今まで使っていたaws-sdkは、v2というバージョンでNode.js18では使えない事がわかった。代わりにv3を使う必要があるとのこと。
対応方法
aws-sdk v3をインポートする。
ただ、インポート部分だけでなくクライアントサービスの使い方も変わったので、コード内の記述も修正しなければいけないようです。S3サービスを例に修正方法をご紹介します。
S3オブジェクトを取得する例
修正前(aws-sdk v2)
const AWS = require('aws-sdk'); const s3 = new AWS.S3(); export const main = async () => { const params = { Bucket: "test-bucket", Key: "hello-s3.txt", }; try { const response = await s3.getObject(params).promise(); const str = await response.Body.transformToString(); console.log(str); } catch (err) { console.error(err); } };
修正後(aws-sdk v3)
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3'); const s3 = new S3Client({}); export const main = async () => { const command = new GetObjectCommand({ Bucket: "test-bucket", Key: "hello-s3.txt", }); try { const response = await s3.send(command); const str = await response.Body.transformToString(); console.log(str); } catch (err) { console.error(err); } };
requireの代わりにimportを使う場合
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
参考
JavaScript (v3) 用 SDK を使用したAmazon S3 の例
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html
AWS SDK を使用して、Amazon S3 バケットからオブジェクトを取得する
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/example_s3_GetObject_section.html
自動移行ツール
コマンド1つでv2からv3へ自動的にコード変換してくれるツールがあるようです。自分は使ってないですが、修正箇所が多い場合は活用してみるのもいいかもですね。
V3 用 JavaScript SDK へのコードの移行
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/migrating-to-v3.html
まとめ
古い技術がサポート終了などで使えなくなるケースがありますが、バージョンアップすると今まで使っていたライブラリなども連鎖して影響受けたりして修正が意外と大変だったりしますね。
-
前の記事
chrome-aws-lambdaをNode.js18に対応させる 2023.12.23
-
次の記事
AWS Lambdaで日本語フォントを使う時のメモ 2023.12.27
コメントを書く