最近正在调研开源工作流项目,从github上克隆的代码,执行npm run dev报错。错误如下:
查找原因
出现了问题,自然要想办法解决。
在网上搜索了一圈,发现该问题早已出现,一般描述的大致原因就是:当
nodejs
升级到17+版本以后,开始支持
OpenSSL 3.0
,而
OpenSSL 3.0
对各种摘要算法做了更严格的限制,可能会导致一些程序运行错误。
但其实,只有这个开源项目出现了问题,所以得搞清楚其中的具体原因,到底是哪些地方影响了项目运行。
而要搞清原因,还得回到错误信息里,仔细查看上图里的错误信息,可以发现:Error 出现在了 compression-webpack-plugin包的 dist\index.js 代码文件,查看该文件,可知主要是用于压缩时创建hash值,这部分的核心代码如下所示:
从上面的代码我们可以发现,compression-webpack-plugin压缩文件使用了node中的crypto 加密模块,使用md4加密算法进行hash计算。
查看nodejs的crypto模块
回到错误源码上,主要是这句代码出错:
_crypto.default.createHash('md4').update(input).digest('hex')
查看nodeJS官方文档
The algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are 'sha256', 'sha512', etc. On recent releases of OpenSSL, openssl list-message-digest-algorithms will display the available digest algorithms.
翻译出来大概意思是:algorithm 取决于平台上 OpenSSL 版本支持的可用算法。例如 'sha256'、'sha512' 等。在最近的 OpenSSL 版本中,openssl list -digest-algorithms 将显示可用的摘要算法。
显示当前运行环境支持md4加密算法,这就奇怪了,那为什么报错呢?继续查看 openssl 3.0 相关的文档,经过寻找,终于发现问题的细节:
OpenSSL 中提供了5个 Provider (它表示算法实现的容器),我们需要了解如下两个:
default:默认,提供了所有标准的内置算法,如果没明确指定则将使用默认算法容器; legacy:遗留,已不常用或者被反对使用的算法,正常情况下不可用,除非显式地指定使用 legacy 容器;
openssl 3.0 正常都是使用 default 容器提供的算法,而 md4 却位于 legacy 算法容器中,所以正常情况下并不支持 md4 算法,因此导致错误。
legacy 算法容器中包含以下算法
解决方法
1、卸载compression-webpack-plugin
治标不治本,导致打包项目文件比较庞大,有得有失
2、在package.json中添加设置
这种方式之前的项目中使用过,只是当时没有研究。而且团队合作中,不同的node版本使用起来会比较麻烦,每次都需要删除/添加。
// 低版本不支持
node: --openssl-legacy-provider is not allowed in NODE_OPTIONS
3、nodejs版本降级或多版本管理
使用nvm管理多版本Node,或者直接降级Node。不过项目繁多,环境也不能经常切换,也是比较麻烦。
小结
解决的方法繁多,根据自己的项目配置选择适合的方案,黑猫白猫,抓住老鼠就是好猫。
可以关注我的公众号,交流相关技术,谢谢支持!
版权归原作者 焚心小记 所有, 如有侵权,请联系我们删除。