nodeを16から18にアップデートした話
はじめに
node16系から18系にバージョンアップした手順を備忘録的に記事にまとめました。
nodeのバージョンアップによるパッケージの依存関係修復については触れません。
前提条件としてnodeのバージョン管理にvoltaを使用しています。
node 16.14.2 からnode 18.12.0へアップデートします。
手順
voltaのnodeのバージョンを上げる
node18の最新のLTSをインストール
$ volta install node@18
voltaにインストールされているバージョンを確認
$ volta list all
$ volta list all
⚡️ User toolchain:
    Node runtimes:
        v6.17.1
        v8.17.0
        v10.24.1
        v12.22.7
        v12.22.11
        v12.22.12
        v14.19.1
        v16.14.2
        v16.15.0
        v16.18.0
        v16.18.1
        v18.12.0 (current @ {プロジェクトのパス})
        v19.0.0
nodeのバージョン指定
$ volta pin node@v18.12.0
nodeのバージョン確認
$ node -v
v18.12.0
node_modulesを再インストール
node_modules削除
$ rm -i -rf node_modules    
yarn.lock削除
$ rm -f yarn.lock
cache削除
$ yarn cache clean  
node_modules再インストール
$ yarn install
これでnodeV18系のnode_modulesが再インストールされました。
動作確認
動作確認としてアプリを起動させると。。。
$ yarn dev
以下のエラーが発生しました。
 ERROR  Error: error:0308010C:digital envelope routines::unsupported 
OpenSSLの互換性エラー
Node16ではOpenSSL1.1を使用していましたが、Node17からはOpenSSL3.0に変更されたことで互換性が取れずにエラーになっているようです。
このエラーを回避するためにnodeのオプションでopenssl-legacy-providerを指定し、古いプロバイダーを使用することで回避できます。
export NODE_OPTIONS=--openssl-legacy-provider
ビルド時にオプションを指定するためにpackage.jsonのscriptsに追記しました。
  "scripts": {
    "dev": "node --openssl-legacy-provider node_modules/.bin/next dev",
  },
ECONNREFUSEDエラー
これでもう一度ビルドしてみるとビルド自体は成功しますが、サーバー側のAPIでECONNREFUSEDエラーが発生しています。クライアント側では叩けているのでサーバー側だけで発生していそうです。
get: http://{エンドポイント} - ECONNREFUSED
node16まではIpv4に接続することがデフォルトになっていたようですが、node18からはIpv6に優先して接続するようになったことが原因のようです。
その関係でIPv6のみ接続が拒否されているためサーバー側でホストが失敗してECONNREFUSEDエラーになっています。
クライアント側だけ成功した原因はわかっていないのですが、クライアント側でIPv6で繋がらない場合はIPv4で接続する設定が効いているのでしょうか?わかる人いれば教えて欲しいです。
こちらのエラーもnodeのオプションでdns-result-orderorderをipv4firstに指定し、IPv4を優先させれば良いです。
本来であればIPv6で繋がらなければIPv4に接続する設定ができれば良いと思うのですが、ここでは暫定的にIPv4を優先する設定を行いました。
export NODE_OPTIONS=--dns-result-order=ipv4first
こちらもscriptに記載しました。
  "scripts": {
    "dev": "node --openssl-legacy-provider --dns-result-order=ipv4first node_modules/.bin/next dev",
  },
最終確認
最後にもう一度ビルドして動作確認をします。
$ yarn dev
パッケージの依存関係が出たら依存関係を調べて修復する必要がありますが、node自体のアップデートはできたので一旦完了です。
おわりに
nodeのアップデート自体はそこまで大きな問題なくできるんですが、問題はパッケージの依存関係ですね。
あとやっぱりvoltaでnodeのバージョン管理する運用がされてると便利ですね。
参考記事
Discussion