Reactのwebアプリをローカルサーバーで起動できなくなった
あるwebサイトを久しぶりにアップデートしようと手を加えて確認しようとした。
$ npm start
すると見たことも無いエラーが表示されたのである。。。
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:69:19)
at Object.createHash (node:crypto:138:10)
at module.exports (/home/yonas/git/server/ui/node_modules/webpack/lib/util/createHash.js:135:53)
at NormalModule._initBuildHash (/home/yonas/git/server/ui/node_modules/webpack/lib/NormalModule.js:417:16)
at /home/yonas/git/server/ui/node_modules/webpack/lib/NormalModule.js:452:10
at /home/yonas/git/server/ui/node_modules/webpack/lib/NormalModule.js:323:13
at /home/yonas/git/server/ui/node_modules/loader-runner/lib/LoaderRunner.js:367:11
at /home/yonas/git/server/ui/node_modules/loader-runner/lib/LoaderRunner.js:233:18
at context.callback (/home/yonas/git/server/ui/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
at /home/yonas/git/server/ui/node_modules/react-scripts/node_modules/babel-loader/lib/index.js:59:103 {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
Node.js v18.17.1
error Command failed with exit code 1.
何だこれは
node.jsのバージョンを上げていたことが原因だった
以前までは問題なくnpm start
ができていたのに、急にできなくなったので環境の問題かな〜と思っていたらその通りでした。。。
OpenSSLがバージョンアップしていた
Node v17.0.0以降では「OpenSSL 1.1.1」に替わって「OpenSSL 3.0」が収録されるようになりました。
プロジェクトで使っているあるライブラリが、サポートしていないOpenSSLのバージョンを使っているということでエラーになってるぽいです
Node.jsが暗号化関連の操作(ハッシュ関数など)を行おうとしたとき、その操作がサポートされていないということですね。
OpenSSLとは??
ハッシュ、共通鍵暗号、公開鍵暗号、署名に関する機能を集約したソフトウェアです。
秘密鍵、公開鍵、サーバ証明書、クライアント証明書を作成する際などに利用されます。
現時点(2022年4月)の最新版は 3.0.2 ですが、Ubuntu 20.04 や RHEL8 ではデフォルトで 1.1.1 がインストールされます。
Ubuntu 22.04(LTS) からは 3.0.2 となるようです。
1.x 系は OpenSSL License (Apache License Version 1.0 ベース) 及び SSLeay License (四条項BDSライセンスベース) が適用されます。
3.x 系は Apache License Version 2.0 ライセンスとなります。
https://www.tohoho-web.com/ex/openssl.html
node.jsでウェブサーバーを実装する時には、 HTTPS 通信時にサーバ証明書が必要です。それらの色々をやってくれる存在って感じですかね!(間違ってたらすいません!)
解決策
じゃどうすればnpm start
できるんじゃい?ということで、一番簡単な解決策は
「Node.jsに旧式のOpenSSLプロバイダを使用するよう指示する」ということらしいです。
ターミナルで👇のコマンドを実行
$ export NODE_OPTIONS=--openssl-legacy-provider
これだけで解決します!
※ただし、この設定はそのターミナルセッションにのみ適用され、ターミナルを閉じるとリセットされます。
では他に解決法はあるのか?
もしreact-script
を使ってる場合
$ npm i react-scripts@latest
私の場合、これで毎回ターミナルで👇のコマンドを実行しなくてもいいようになりました。
$ export NODE_OPTIONS=--openssl-legacy-provider
他にもpackage.json
のスクリプト部分に直接設定することも可能なようです。
"scripts": {
"start": "react-scripts start --openssl-legacy-provider"
}