文章目录

  • 查找原因
    • webpack源码与配置
    • 查看nodejs的crypto模块
    • 查看openssl问题
  • 解决方法
    • 升级webpack
    • 提供legacy容器环境
      • 增加系统环境变量
      • 在package.json中添加设置
    • nodejs版本降级或多版本管理
  • 最后

最近,发现自己电脑上的nodejs版本居然还是14+,而最新的已经到了18+,由于并没有使用任何版本管理工具,于是直接升级到了最新的版本(v18.14.1),然后悲剧就发生了。
电脑里以往的绝大部分的Vue和React项目,在执行脚本构建命令如 npm run devnpm run build 时,都出现同样的错误,导致构建失败,并且报类似下面的错误:

查找原因

出现了问题,自然要想办法解决。
在网上搜索了一圈,发现该问题早已出现,一般描述的大致原因就是:当 nodejs 升级到17+版本以后,开始支持 OpenSSL 3.0,而 OpenSSL 3.0 对各种摘要算法做了更严格的限制,可能会导致一些程序运行错误。

webpack源码与配置

但其实,并不是所有的项目都会出现,比如使用了最新版本的 webpack 工具的项目就能够正常运行,所以得搞清楚其中的具体原因,到底是哪些地方影响了项目运行。
而要搞清原因,还得回到错误信息里,仔细查看上图里的错误信息,可以发现:Error 出现在了 webpack 包的 lib/util/createHash.js 代码文件,查看该文件,可知主要是用于创建hash值,这部分的核心代码如下所示:

switch (algorithm) {case 'debug':return new DebugHash()default:return new BulkUpdateDecorator(require('crypto').createHash(algorithm))
}

从上面的代码,我们可以发现:webpackhash 使用了 nodejs 中的 crypto 加密模块,根据传入的算法名称创建 Hash 对象。

我们直接代码测试,进一步发现当前版本的 webpack,这里的参数 algorithm 算法都是使用的 md4,搜索 webpack 源码还能发现很多地方直接写死了 md4 算法名:


而查看webpack文档,也有类似的介绍。
webpack 的源码里,我们还找到了一个配置属性:output.hashFunction,在webpack配置说明文档里也找到该属性的说明:


如上图所示,该属性定义webpack可使用的散列算法,默认也是 md4

查看nodejs的crypto模块

在回到错误源码上,主要是这句代码出错:

require('crypto').createHash(algorithm)

上面的代码里调用了 crypto 模块的 createHash 方法,我们查看该方法的文档,可以发现有这样一段话:

algorithm 取决于平台上 OpenSSL 版本支持的可用算法。
例如 'sha256''sha512' 等。
在最近的 OpenSSL 版本中,openssl list -digest-algorithms 将显示可用的摘要算法。

可见 webpack 源码里的 algorithm 就表示 OpenSSL 能够支持的可用算法,——在源码注释里也有解释。
md4 显然也是其中一种算法,但这里却创建失败了。
到这里,我们已能发现问题所在:crypto 模块的 createHash 方法在使用 md4 算法创建 Hash 对象时失败,无法创建,因此报错。

为什么会报错呢?继续寻找答案,我们直接在当前node环境下调用该方法:

require('crypto').createHash('md4')

立马报错:


错误信息和项目中的类似,出现不支持 unsupported,这里还出现了 opensslErrorStack 错误栈,初始化失败,网上提到 openssl 3.0 不支持 md4 算法看上去是正确的,但为什么不支持呢?

查看openssl问题

我们先了解下这里提到的 openssl 是什么?OpenSSL 是一个强大的安全套接字层密码库的开源项目,它提供了一个功能丰富 openssl 安全工具包,拥有多种加密算法,能处理对称与非对称算法密钥、数字证书编解码等等。

而上文也提到在 nodejs 的加密模块中,生成hash就借助了 openssl 等能力,其中通过命令 openssl list -digest-algorithms 可以查看当前平台支持哪些算法,在命令行执行后,可以发现有几十种算法,而 md4 也名列其中:


那又为什么会创建失败呢,继续查看 openssl 3.0 相关的文档,经过寻找,终于发现问题的细节:

  • OpenSSL 中提供了5个 Provider (它表示算法实现的容器),我们需要了解如下两个:

    • default:默认,提供了所有标准的内置算法,如果没明确指定则将使用默认算法容器;
    • legacy:遗留,已不常用或者被反对使用的算法,正常情况下不可用,除非显式地指定使用 legacy 容器;
  • openssl 3.0 正常都是使用 default 容器提供的算法,而 md4 却位于 legacy 算法容器中,所以正常情况下并不支持 md4 算法,因此导致错误。

legacy 算法容器中,包含 MD2、MD4、MDC2、RMD160、CAST5、BF、IDEA、SEED、RC2、RC4、RC5 和 DES 等算法。

解决方法

升级webpack

从前文可知,目前环境出现的问题,主要是 webpack 的使用了 md4 算法导致错误,可见还得在 webpack 工具上下功夫。

注意:只改变 webpack 的配置属性 hashFunction 值为其他算法,无法解决该问题,是因为 webpack 中很多地方写死了 md4 字符串。

如果我们把 webpack 进行升级到较新的版本,就可以解决此类问题。
据查,自 5.61.0 版本开始,webpack 就已解决了这个问题,可以查看同样创建hash的源码,新修改的如下所示:

switch (algorithm) {//...case "md4":if (createMd4 === undefined) {createMd4 = require("./hash/md4");if (BatchedHash === undefined) {BatchedHash = require("./hash/BatchedHash");}}return new BatchedHash(createMd4());// ...default:if (crypto === undefined) crypto = require("crypto");return new BulkUpdateDecorator(() => crypto.createHash(algorithm),algorithm);
}

以上代码可看出,针对 md4 已经做了专门处理,不再直接使用 crypto 模块创建,而是新建 md4 算法。

针对使用 @vue/cli-servicereact-scripts 工具构建的项目,由于还是依托 webpack,所以对应工具进行升级即可,其中:

  • @vue/cli-service5.0.1 版本开始,已经支持 webpack@5.61.0
  • react-scripts5.0.0 版本开始,已经支持 webpack@5.61.0

但是,由于升级构建工具,可能随之带来很多不可知的问题,不少依赖包都会因为不支持而报错,升级带来的成本并不小,所以很多人并不愿意升级构建工具。

当然,我们也可以自己修改 webpack 源码解决问题,只需要再创建hash对象的地方拦截 md4 换种算法就可以了,但还需要更改另外一个依赖包 terser-webpack-plugin,这个库里也有 md4

提供legacy容器环境

根据上文提到的错误原因,可知是由于我们使用了 openssllegacy 算法容器里的算法 md4,并不被标准默认容器支持,所以需要显式指定算法容器环境。
指定 legacy 算法容器,使用 --openssl-legacy-provider,网上提供的很多解决方案,都是基于这个原则去做的,只不过都不交代具体的原因。

增加系统环境变量

Windows系统下,可在系统环境变量里添加一个新的变量:NODE_OPTIONS,值为:--openssl-legacy-provider
如下图所示:


需要注意的是,
通过设置系统变量,我们只能解决 Git Bash 在系统右键启动时的构建命令正确执行,或者直接启动 git-bash.exe 软件,即单独的命令窗口能有效解决问题:


而在VSCode中添加的 git-bash 工具,却并不起作用,即在下面的窗口下执行构建命令时仍然会报错:

我并没有找到VSCode设置git-bash时有啥特殊的配置,会导致两者之间有差异,如果有人了解,希望可以在评论里告知。

在package.json中添加设置

一个能在新版本nodejs中完整解决问题的方案,就是在 package.json 配置的脚本命令中,增加对应的设置,如下所示:

"dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"build": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",

即增加 set NODE_OPTIONS=--openssl-legacy-provider 命令设置,就可以在 Git Bash 的右键命令以及VSCode中都能正常执行构建命令了。

注意,如果在 package.json 中添加脚本命令设置,会导致使用老版本的同事,无法执行脚本,因为老版本 nodejs 并不支持设置 --openssl-legacy-provider 属性值,将有如下提示并中断构建执行:

node: --openssl-legacy-provider is not allowed in NODE_OPTIONS

nodejs版本降级或多版本管理

另外还有一种方案,就是不要使用最新版本的 nodejs,降级后重新使用V16的版本,低版本的 nodejs 可以保障项目正常运行。
或者,还可以使用 nodejs 的多版本管理工具,能够自由切换不同的版本,同样满足要求。关于 nodejs 版本管理的简单介绍,可查看博文 node和npm如何升级版本。

但是,已经使用了新版本的nodejs,再去用老版本的,也多少有些不那么回事。

最后

本文详细描述了 nodejs 升级后引起的前端老旧项目中构建工具生成hash报错的问题(0308010C:digital envelope routines::unsupported),以及给出的几种解决方案。
这几种解决方案各自都存在一些不完美的地方,但都能解决当前构建错误,可以根据自己的实际需求来确定使用哪种方案。

nodejs升级引起的构建错误:0308010C:digital envelope routines::unsupported相关推荐

  1. Vue 报错error:0308010C:digital envelope routines::unsupported

    Vue 报错error:0308010C:digital envelope routines::unsupported 出现这个错误是因为 node.js V17版本中最近发布的OpenSSL3.0, ...

  2. Error: error:0308010C:digital envelope routines::unsupported(Vue2项目报错)

    问题描述 在 终端输入 npm run dev 命令,项目运行报错 Error: error:0308010C:digital envelope routines::unsupported 问题原因 ...

  3. npm run serve 报错:Error: error:0308010C:digital envelope routines::unsupported

    项目场景: vue项目npm install之后运行报错 问题描述 npm run serve 报错:Error: error:0308010C:digital envelope routines:: ...

  4. npm run dev error:0308010C:digital envelope routines::unsupported

    error:0308010C:digital envelope routines::unsupported 发现场景:npm run dev 造成下方错误 问题产生原因:node 版本过高 在node ...

  5. npm start报错Error: error:0308010C:digital envelope routines::unsupported

    (41条消息) npm run dev 报错:Error: error:0308010C:digital envelope routines::unsupported_爱的叹息的博客-CSDN博客 n ...

  6. 项目报错error:0308010C:digital envelope routines::unsupported

    描述 在终端使用npm指令运行项目时报错error:0308010C:digital envelope routines::unsupported 原因 出现这个错误是因为 node.js V17版本 ...

  7. npm Error: error:0308010C:digital envelope routines::unsupported

    Error: error:0308010C:digital envelope routines::unsupported 错误原因 node版本高于16,项目的版本不高于16,node17之后更新了O ...

  8. VUE报错 error:0308010C:digital envelope routines::unsupported

    新克隆的项目启动时报错Error: error:0308010C:digital envelope routines::unsupported 前期安装过低版本Node,后期换成了最新版Node,后来 ...

  9. npm run dev的时候出现报错:Error: error:0308010C:digital envelope routines::unsupported以及‘export’ 不是内部或外部命令

    1.今天在运行webpack打包工具的时候,出现了以下错误: node:internal/crypto/hash:67this[kHandle] = new _Hash(algorithm, xofL ...

最新文章

  1. Linq 等式运算符:SequenceEqual
  2. 结构体的嵌套 自身嵌套 相互嵌套
  3. 【错误记录】BLE 蓝牙搜索失效 ( 关闭了 GPS 定位导致的问题 | 蓝牙串口工具推荐 )
  4. css背景上能添加文字,CSS3怎么为文字添加背景?
  5. IA-32系统编程指南 - 第三章 保护模式的内存管理【2】
  6. java基础的三个框架,进阶学习资料!
  7. getdevicecaps在哪个头文件里_一招定胜负,while (true) 和 for (;;) 到底哪个更快
  8. PROTEUS元件库元件称呼 .
  9. 一步一步学习Git(2)——Git基本操作
  10. 经验模态分解(EMD)
  11. Java导出Excel每列求和,POI导出excel执行自动求和
  12. 完全背包问题 旅游付费
  13. 十年前开发的平板游戏:HyllCube 三维四子棋游戏,获得了全国一等奖
  14. 大数据难学吗?如何学习大数据?(附学习路线)
  15. 用Eclipse建立从Vuze/Azureus工程并编译运行的方法
  16. AlexNet论文翻译与解读
  17. python如何写生日快乐说说_一句祝自己生日快乐的说说
  18. 西安电子科技大学网络与信息安全学院专硕951考研回顾
  19. 如何使用Audition消除音乐中的人声
  20. 国内技术帝不输国外 CryEngine 3引擎下“混血编辑器”诠释究极画质

热门文章

  1. ubuntu 14 编译视频第三方库ijkplayer,能够在winows下使用
  2. 最小人工智能硬件资源JetsonNano VS 树莓派4B
  3. Scala知识点总结-思维导图
  4. 锋迷商城 用户注册登录前端实现
  5. c语言包头文件bts,c – 使用bts汇编指令和gcc编译器
  6. 【强化学习】开源环境集(魂斗罗、星际争霸等都有!)
  7. 钛碳化铝(Ti3AlC2)在实验检测领域中的应用
  8. phh mysql语法_MySQLPHP语法
  9. Flash在多标签浏览器中的问题
  10. 手机网站开发及手机中图片加速显示img的Canvas方法