Ruby on Rails 6.1 で、Webpacker を止めて, jsbundling-rails + webpack に切り替える方法について。
Fedora 36 で Webpacker を利用するアプリケィションを実行すると, 次のようなエラーが生じる.
node:internal/crypto/hash:67
this[kHandle] = new _Hash(algorithm, xofLen);
^
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:67:19)
at Object.createHash (node:crypto:130:10)
at module.exports (/home/hori/repos/netsphere/rails-examples/LoginSample-sorcery-1/node_modules/webpack/lib/util/createHash.js:135:53)
at NormalModule._initBuildHash (/home/hori/repos/netsphere/rails-examples/LoginSample-sorcery-1/node_modules/webpack/lib/NormalModule.js:417:16)
中略
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED
'
Fedora 36 は nodejs-16.14.0 と openssl-3.0.2 の組み合わせ。ググると Node.js v17 の話題は多く見つかるが、なかなか v16 のが見当たらない。しかも, Node.js v17 の話題であっても、古い挙動にする方法ばかり。
Building Node.js によれば, Node.js v16 のデフォルトは OpenSSL-1.1. configure --openssl-is-fips でビルドすれば OpenSSL v3.0 を利用する。後者でビルドされているのだろう。
md4 がハードコードされているのが原因。webpack の対応するバグ報告はこちら; Webpack Hash is not FIPS-Compliant #13572. 2022年5月現在, webpack v4.46.0 が v4 系列の最新。まだ修正されていない。この組み合わせでは通らない。
Workaround はこちら. 直接 webpack にパッチを当てる。ヒドい。
$ find node_modules/webpack/lib -type f -exec sed -i 's|md4|sha512|g' {} \; $ find node_modules/compression-webpack-plugin/dist -type f -exec sed -i 's|md4|sha512|g' {} \;
createHash()
関数を置き換えてしまう、という方法もあるようだ。まだこちらのほうがマシか?
Webpacker は, 結局 v6 が リリースされることなく, 完全に retire した。
Webpacker v6 の開発途中から引き継いで、正統な後継は Shakapacker. shakacode/shakapacker: Use Webpack to manage app-like JavaScript modules in Rails
ただ、もともと Webpacker は, 屋上屋を架す、webpack の設定を隠蔽して訳が分からなくなりやすい、など評判が非常に悪かった。Rails 7 であっさり廃止になったこともあり、わざわざ選ぶこともない。
上記のエラーは, Webpacker が webpack v4.46.0 に依存しているのが問題。単純に Webpacker を止めて, 素の webpack v5 系列を使えばよい。この対策が一番簡単で確実。
包括的な手順はこちら; jsbundling-rails/switch_from_webpacker.md at main · rails/jsbundling-rails
Gemfile
ファイルで, gem 'webpacker'
をコメントアウトし, gem "jsbundling-rails"
を加える。
JavaScript エントリポイントが app/javascript/packs/application.js
ファイルから app/javascript/application.js
に替わる. 内容を適宜、移動する。
app/views/layouts/application.html.erb
ファイルの javascript_pack_tag()
(Webpacker::Helper
クラス) を javascript_include_tag()
に変更する。
次のファイル、ディレクトリを削除;
package.json
ファイルを適宜、調整. Webpacker 関連と webpack-dev-server
を削除.