every Tech Blog

株式会社エブリーのTech Blogです。

Node.js v18.16.1 への バージョンアップを行っています

はじめに

はじめまして。DELISH KITCHEN 開発部 の 羽馬(@NaokiHaba)と申します。

この記事では、DELISH KITCHEN 開発部 で 行っている Node.js のバージョンアップの手順と、その際に発生した問題とその対応についてご紹介します。

対象読者

この記事は、Node.js のバージョンアップを行いたいが、どのような手順で行えばよいかわからない方や、Node.js のバージョンアップを行った際に発生した問題の対応方法を知りたい方を対象としています。

この記事で紹介する環境

この記事で紹介する環境は以下の通りです。

  • Node.js v16.13.1
  • npm v8.1.2
  • nodenv v1.4.1

バージョンアップの背景

DELISH KICTHEN WEB では フロントエンドのランタイムとして Node.js を採用しています。

tech.every.tv

現在利用している Node.js のバージョンは v16.13.1 ですが、2023 年 9 月 11 日 に EOL が予定されているため、今回 Node.js のバージョンアップを行うことにしました。

バージョンアップの手順

リリースノートの確認

Node.js のバージョンアップを行う際は、リリースノートを確認し、バージョンアップによって発生する可能性のある問題を事前に把握する必要がありました。

nodejs.org

nodejs.org

OpenSSL に関する変更が多く含まれていることから、Node.js のバージョンアップによって発生する可能性のある問題として、以下のようなものが考えられました。

  • 変更前のバージョンの Node.js で利用していた OpenSSL のバージョンと、変更後のバージョンの Node.js で利用している OpenSSL のバージョンが異なることによって、OpenSSL に関する問題が発生する可能性がある

Node.js のバージョンアップ

Node.js のバージョンアップは、nodenvinstall コマンドを利用して行います。

# 現在のバージョン情報を確認
$ node -v
16.18.0

# .node-version を更新
$ vi .node-version

# .node-version
18.16.1

# nodenv で 18.16.1 をインストール
$ nodenv install $(cat .node-version) # 18.16.1

$ node -v
18.16.1

.node_modules・ package-lock.json を再作成する

Node.js v16.18.0 でインストールした node_modules を、Node.js v18 で利用すると依存関係の不整合等が発生する可能性が高いことから、node_modules を削除し、package-lock.json を再作成します。

$ rm -rf node_modules package-lock.json

# npm のキャッシュで古いバージョンのパッケージが残っている可能性があるため、キャッシュを削除
$ npm cache clean --force

# キャッシュがクリアされたかどうかを確認
$ npm-cache verify

# package-lock.json を再作成
$ npm install

OpenSSL の 互換性エラー

Node.js v18 でアプリケーションが正常に動作するか確認すると、以下のようなエラーが発生しました。

$ npm run dev

# 以下のようなエラーが発生する場合は、後述の「`Node.js` v18 での `crypto` モジュールの変更」をご確認ください。
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)

Node.js v18 での crypto モジュールの変更

Node.js v18 では、crypto モジュールのデフォルトの暗号化方式が変更されたことにより、Node.js v16 で正常に動作していたアプリケーションが正常に動作しなくなる可能性があります。

対象方法としては、以下の 2 つが考えられます。

  • webpack のバージョンアップ
  • 暫定措置として package.jsonscriptsNODE_OPTIONS=--openssl-legacy-provider を追加する

本来は webpack のバージョンアップを行うことが望ましいですが、webpack のバージョンアップには時間がかかるため、暫定措置として package.jsonscriptsNODE_OPTIONS=--openssl-legacy-provider を追加することで対応しました。

Error when running build-storybook with Node 17 · Issue #16555 · storybookjs/storybook · GitHub

nodejs.org

{
  "scripts": {
    "dev": "NODE_OPTIONS=--openssl-legacy-provider app/server/index.js --watch"
  }
}

上記の設定を追加することで、Node.js v18 での crypto モジュールのデフォルトの暗号化方式を変更することができます。

以上の手順で、Node.js v18 へのバージョンアップを完了することができました。

Dockerfile の変更

Node.js のバージョンアップに伴い、DockerfileFROM で指定している Node.js のバージョンを変更します。

# 変更前
FROM node:14.17.3-alpine3.14

# 変更後
FROM node:18-alpine3.16

最後に

Node.js のバージョンアップは、Node.js のバージョンアップによって発生する可能性のある問題を事前に把握し、対応する必要があります。

この記事が、Node.js のバージョンアップを行う際の参考になれば幸いです。