Webpack构建失败,显示ERR_OSSL_EVP_UNSUPPORTED错误。

476

我遇到了一个Webpack构建过程的问题,突然出现了以下错误...

<s> [webpack.Progress] 10% building 0/1 entries 0/0 dependencies 0/0 modules
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 BulkUpdateDecorator.hashFactory (/app/node_modules/webpack/lib/util/createHash.js:155:18)
    at BulkUpdateDecorator.update (/app/node_modules/webpack/lib/util/createHash.js:46:50)
    at OriginalSource.updateHash (/app/node_modules/webpack-sources/lib/OriginalSource.js:131:8)
    at NormalModule._initBuildHash (/app/node_modules/webpack/lib/NormalModule.js:888:17)
    at handleParseResult (/app/node_modules/webpack/lib/NormalModule.js:954:10)
    at /app/node_modules/webpack/lib/NormalModule.js:1048:4
    at processResult (/app/node_modules/webpack/lib/NormalModule.js:763:11)
    at /app/node_modules/webpack/lib/NormalModule.js:827:5 {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
command terminated with exit code 1

我曾尝试通过谷歌搜索ERR_OSSL_EVP_UNSUPPORTED webpack,结果几乎没有有用的结果,但它确实突出了使用由OpenSSL(显然已经不推荐使用?)提供的MD4生成哈希的问题。

webpack.config.js代码如下:

const path = require('path');
const webpack = require('webpack');

/*
 * SplitChunksPlugin is enabled by default and replaced
 * deprecated CommonsChunkPlugin. It automatically identifies modules which
 * should be splitted of chunk by heuristics using module duplication count and
 * module category (i. e. node_modules). And splits the chunks…
 *
 * It is safe to remove "splitChunks" from the generated configuration
 * and was added as an educational example.
 *
 * https://webpack.js.org/plugins/split-chunks-plugin/
 *
 */

/*
 * We've enabled TerserPlugin for you! This minifies your app
 * in order to load faster and run less javascript.
 *
 * https://github.com/webpack-contrib/terser-webpack-plugin
 *
 */

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: './src/js/scripts.js',

    output: {
        path: path.resolve(__dirname, 'js'),
        filename: 'scripts.js'
    },

    devtool: 'source-map',

    plugins: [new webpack.ProgressPlugin()],

    module: {
        rules: []
    },

    optimization: {
        minimizer: [new TerserPlugin()],

        splitChunks: {
            cacheGroups: {
                vendors: {
                    priority: -10,
                    test: /[\\/]node_modules[\\/]/
                }
            },

            chunks: 'async',
            minChunks: 1,
            minSize: 30000,
            name: 'true'
        }
    }
};

我该如何将Webpack使用的哈希算法更改为其他算法?


2
https://github.com/facebook/create-react-app/issues/11562 这个链接详细说明了为什么需要将 Node.js 降级到 v16.13.0。 - Abhinav Saxena
安装 nvm,然后检查你的 Node 版本。 使用 nvm list 命令来查看你安装的 Node 版本。 然后使用 nvm use (node 版本号) 命令来切换到指定版本的 Node。 - Majdi Mohammad
1
降级到16.13.1对我有用。 - Jan Peeter
12个回答

692

我通过以下方式成功修复了它:

export NODE_OPTIONS=--openssl-legacy-provider

sachaw评论了Node.js v17.0.0 - Error starting project in development mode #30078

但他们说他们已经修复了它:ijjk评论了Node.js v17.0.0 - Error starting project in development mode #30078

嗨,这在 Next.js 的 v11.1.3-canary.89 中已更新,请更新并试试!

对我来说,只有上面的注释才有效。

我还想指出,npm run start可以使用-openssl-legacy-provider ,但npm run dev则不行。

看起来有一个补丁:Node.js 17: digital envelope routines::unsupported #14532

我个人降级到了16-alpine


79
PowerShell: $env:NODE_OPTIONS="--openssl-legacy-provider"翻译:在PowerShell中,将环境变量$env:NODE_OPTIONS的值设置为"--openssl-legacy-provider" - Hex
9
在启动服务器之前:"scripts":{"debug":"NODE_OPTIONS='--openssl-legacy-provider' next dev -p 5000"} - Jan
16
你可以一次性运行所有内容:NODE_OPTIONS=--openssl-legacy-provider npm start - Seralto
9
在 Fedora 36 上,我使用 Node v16.14.0 无法正常工作:node: --openssl-legacy-provider is not allowed in NODE_OPTIONS - Jasper Siepkes
3
在 Windows 上使用 React,编辑 package.json 文件:{ "scripts": { "start": "set \"NODE_OPTIONS=--openssl-legacy-provider\" && react-scripts start" } } - pushStack
显示剩余14条评论

183

我也曾遇到过这个问题。我不小心使用了最新的Node.js(撰写时为17.0),而没有使用我原本想要安装的LTS版本(14.18)。将我的Node.js降级到LTS版本后,问题得到了解决。


22
我也是。将版本降级至16.x 也可以解决问题。根据https://nodejs.org/en/about/releases/,它的LTS版本将于一周后开始(2021年10月26日),所以我选择了它。 - Gustav
3
我遇到了v16.13.0的问题。 - Trip
6
确认从v17.2.0降级到v16.13.1的操作正常运行。 - Mauzzz0
4
感谢您。通过nvmnvm-windows,Node版本管理器可以轻松切换版本,非常出色。 - tno2007
1
在采纳可能会导致您的应用程序存在安全漏洞的建议之前,请查看此处相同问题的答案:https://dev59.com/0VEG5IYBdhLWcg3wPXtF#73027407在最理想的情况下,找到正确的解决方案而不是通过黑客手段解决问题。这样做也许有效,但并不意味着它是正确的。 - Justin Greywolf
显示剩余7条评论

76

这并不是我的真正答案,但我发现这个解决方法/黑客/可以解决我的问题:为GitHub项目检入代码…请查看这里的错误注释。

在使用npm install更新后,我遇到了ERR_OSSL_EVP_UNSUPPORTED。

我将以下内容添加到node_modules\react-scripts\config\webpack.config.js文件中。

const crypto = require("crypto");
const crypto_orig_createHash = crypto.createHash;
crypto.createHash = algorithm => crypto_orig_createHash(algorithm == "md4" ? "sha256" : algorithm);

我尝试了Ryan Brownell的解决方案,但最终出现了不同的错误,但是这个方法可行...


1
这在 Webpack4 中对我很有效。我在 12LTS / 17 之间反复切换,这是一个大的时间节省器。 - Daniel B. Chapman
2
这应该是2021年的最佳答案。感谢您描述文件夹位置,解决了我的问题。我之前尝试过将变量导出到环境的解决方案,但它导致VSCode无法加载。因此,这种方法可以解决问题,而不会全局影响其他程序。 - Terry
那么当 react-scripts - 现在是3.0.1或3.4.4 - 获取到新的版本时,我们就必须添加代码了吗? - Timo
它也在应用程序自己的config/webpack.config.js文件中工作,所以是一个很好的解决方案! - szabozoltan
终于有一个真正有效的解决方案了,它不会让我们处于脆弱状态,并且不假设特定的项目设置(这可以放在主要项目配置文件中)。谢谢! - Pluckerpluck
这对我有用:const crypto = require("crypto"); const crypto_orig_createHash = crypto.createHash; crypto.createHash = algorithm => crypto_orig_createHash(algorithm == "md4" ? "sha256" : algorithm); - undefined

66

Ryan Brownell的答案是Webpack v5.54.0+的理想解决方案。

如果您使用的是较旧版本的Webpack,则可以通过将哈希函数更改为未被弃用的函数来解决此问题。(它默认为古老的md4,OpenSSL已经移除了对其的支持,这是错误的根本原因。)支持的算法是由crypto.createHash支持的任何算法。例如,要使用 SHA-256

module.exports = {
    output: {
        hashFunction: "sha256"
    }
};

最后,如果你无法更改Webpack配置(例如,如果它是运行Webpack的传递依赖项),你可以启用OpenSSL的旧版提供程序来在Webpack构建期间暂时启用MD4。这是最后的手段。创建一个名为openssl.cnf的文件,并添加以下内容…

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

然后在运行Webpack时将环境变量OPENSSL_CONF设置为指向该文件的路径。


10
事实证明 hashFunction 修复可以有所帮助,但可能不够:Webpack 4.x 中的 ConcatenatedModule 优化器硬编码使用了 MD4,因此如果您的构建过程中使用它,您可能需要采用 openssl.cnf 方法。我认为这可能是 Vue CLI 4.x 项目的一般情况。 - Peter

62

Webpack v5.54.0+提供了一种哈希算法,不依赖于OpenSSL。

要使用这个哈希函数,需要修改webpack.config.cjs中的output键,加入hashFunction: "xxhash64"选项,以依赖于npm提供的依赖而不是操作系统提供的依赖。

module.exports = {
    output: {
        hashFunction: "xxhash64"
    }
};

26
我遇到了“Error: Digest method not supported”的错误。 - Jack
4
同意。Webpack 升级解决了我的问题。我一开始使用的是 React 17,然后升级到了 React 18,这个版本带来了 Webpack 5.74.0 => 问题解决了。 - tswaehn
2
如果您在webpack 5.54+和node 17+上仍然遇到此错误,请查看堆栈跟踪。在我的情况下,babel-loader: 8.2.2也使用了一个已弃用的哈希函数。升级到babel-loader: 8.3.0可以解决这个问题。 - bendytree
我遇到了与@bendytree相同的情况。事实证明,我根本不需要使用hashFunction webpack配置。升级到babel-loader: 8.3.0解决了这个问题。看起来它实际上是在8.2.4中修复的:https://github.com/babel/babel-loader/releases/tag/v8.2.4。 - Eli Dupuis
xxhash64现在也消失了...你可以尝试使用不同的变体,将hashFunction切换为:"sha256"...但是我在下一层仍然遇到了问题(可能是因为对md4的硬编码使用)。 - Zargold

26

在 Node.js 17.0.0 的 发行说明 中提到了这个错误,并提供了一种建议的解决方法:

如果你在使用 Node.js 17 时遇到了 ERR_OSSL_EVP_UNSUPPORTED 错误,很可能是你的应用程序或所使用的模块正在尝试使用 OpenSSL 3.0 默认情况下不再允许的算法或密钥大小。一个命令行选项 --openssl-legacy-provider 已添加作为这些加强限制的临时解决方法,以恢复旧版本的提供者。


3
我没有在这里工作。 :(--openssl-legacy-provider 在 NODE_OPTIONS 中不被允许。 - Cesarvspr
5
@Cesarvspr 你需要将其添加到环境变量中,而不是作为npm命令的参数。 NODE_OPTIONS='--openssl-legacy-provider' npm run build - Cristian
谢谢,你说得对。经过一些研究,我已经弄清楚了。 - Cesarvspr

23

我也面临过同样的挑战,但你只需要将Node.js降级到16.13版本即可,这样一切都可以正常工作。在下载页面中下载LTS版本,而不是当前版本。


1
这个有效。我只是使用了“n”来更新到lts,然后它就开始对我起作用了。 - Hrithik Tiwari
我为我的Angular项目使用了16.20.0 LTS版本。 :) - Naveen Kumar V

22

我在使用Laravel Mix(Webpack)时遇到了这个问题,并且通过在文件package.json中添加脚本开头的NODE_OPTIONS=--openssl-legacy-provider(参考Jan's answer)来解决了它:

package.json:

{
  "private": true,
  "scripts": {
    "production": "cross-env NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider  node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "dependencies": {
    ...
  }
}

21

尝试将你的Webpack版本升级至5.62.2。


这应该被接受了,升级WebPack解决了我的问题。谢谢!! - 7FigureSwagger
1
我使用的是Webpack 5.81.0,仍然存在这个问题。 - cdalxndr
这对我没用。我更新了我的webpack到提到的版本,但是还是不起作用。我有什么遗漏吗? - undefined

13

在我使用 Next.js 开发的一个项目中,我遇到了同样的问题。解决方案是这样的:我按照以下方式运行项目,然后解决了这个问题。

cross-env NODE_OPTIONS='--openssl-legacy-provider' next dev

对于使用Vue 2的用户,您可以简单地添加NODE_OPTIONS='--openssl-legacy-provider',不包括cross-env - JPilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接