written by naoketa(Naoki Tazawa)
はじめに
Node.js 16のLTS版のEOSLは、当初2024/04を予定していたものの、内部で利用しているOpenSSLのEOSLなどに伴ってNode.js 16自体も2023/09/11でEOSLに早められました。 これに伴ってNode.jsのLambdaランタイムでもNode.js 16系のEOSLを迎えることになり、直近の9月でまずはLambdaの更新自体が出来なくなり、その後は利用自体もできなくなってしまいます。 (2024年1月追記:いつのまにか、Node.16系のEOSLが2024年6月まで延長されていました。 なるべく最新情報の記載は英語版の記事を見た方が良さそうです。 )
これまで手軽なツール類にNode.js 16系を多く使っていたこともあり、慌ててEOSLの対応を行なっているのですが、普段はインフラをメインに触っているエンジニアとしては色々とハマるところがありました。
特にLambdaのBlueprintで提供されるLambdaのNode.jsのコードは16系で書かれているものも多く、また18系向けのコードなどは現時点で公開されていないため、自前でバージョンを上げて書き直す&テストし直すものがあり色々ハマった点を記載します。
JavaScriptモジュールシステムの変更
試しにLambdaのコンソール上でNode.js 18系のランタイムで関数を作成すると、デフォルトで作成されるファイルが、これまでのindex.js
がindex.mjs
に変わっています。
これはLambdaのJavaScriptランタイムのデフォルトで利用するモジュールシステムがCommonJSから、ES Modules (ESM)に変更されたことによるものです。
Node.jsでのサーバーサイド開発ではCommonJSが標準でしたが、最近のバージョンのNode.jsではES Modulesもサポートされています。またフロントエンドの開発では、ES Modulesが多く、Webpackなどのモジュールバンドラーを使用してES Modulesを利用することが増えてきているイメージです。
ということで、Lambda上のソースコードおよびバンドルしているCICD様のツール類も全体的にES Modulesベースの書き方に変更しています。 CommonJSから、ES Modules (ESM)への変更自体はLambdaに限らず、Web上で有用な記事が多く出ているためこちらを参照いただければと思います。 いずれESMには書き換えが必要なため、いくつかのLambdaはESMへ更新を行いましたが、個人的には依存関係の整理など含めてこちらの作業にかなりの時間を費やしました。
aws-sdk v2→v3への変更
LambdaのNode.js 18系のイメージで利用できるaws-sdkのバージョンがv2からv3に変更になっています。これによりそのままaws-sdk v2を使った既存コードを動かすと「そんなモジュールはない」と怒られる様になります。 aws-sdkのv3へのバージョンアップで非推奨や利用ができなくなるAPIについては以下に記載があります。
https://github.com/aws/aws-sdk-js-v3/blob/main/UPGRADING.md
その他AWS側の例外処理など全体的に変わっているお作法があるので、以下のAWS公式のv3のコードサンプルをまずは眺めてから移行に着手すると作業が進めやすいかと思います。
https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code
また個人的には以下AWSブログで紹介されているように、v3向けのmockライブラリが利用できるようになり、ローカルでのモックを使ったテストが書きやすくなっており気に入っております。
https://aws.amazon.com/jp/blogs/developer/mocking-modular-aws-sdk-for-javascript-v3-in-unit-tests/
さいごに
冒頭でLambdaのBlueprintで提供されるLambdaのNode.js 16系のコードについての移行について記載しましたが、利用したい機能や開発チームによってはPython3系など別言語のBlueprintを使うというのも手になります。(Python3系の方が昨今のバージョンでの対応は少ないイメージです。) ただし結局のところ全体的なテストが必要になること、もちろん開発チームの慣れもあるので総合的に判断してNode.jsのランタイムバージョンアップを行うのか等考える必要が出てきます。