Skip to content

ERR_OSSL_EVP_UNSUPPORTED Webpack 构建错误解决方案

问题描述

当使用 Node.js 17+ 版本运行 Webpack 构建时,可能会遇到以下错误:

none
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)

这个错误通常伴随着 OpenSSL 相关的堆栈跟踪信息,表明数字信封例程不支持某些操作。

错误原因

此问题源于 Node.js 17+ 版本中 OpenSSL 3.0 的引入,它移除了对 MD4 算法的默认支持。而 Webpack 在早期版本中默认使用 MD4 作为哈希算法,导致在构建过程中出现兼容性问题。

解决方案

根据不同的使用场景和需求,提供了多种解决方案:

方案一:设置环境变量(推荐临时解决方案)

在运行 Webpack 命令前设置环境变量:

bash
export NODE_OPTIONS=--openssl-legacy-provider
npm run build
batch
set NODE_OPTIONS=--openssl-legacy-provider
npm run build
powershell
$env:NODE_OPTIONS = "--openssl-legacy-provider"
npm run build

这个方案启用 OpenSSL 的旧版提供程序,临时恢复对 MD4 算法的支持。

注意

此方案为临时解决方案,长期来看应该考虑使用更持久的解决方案。

方案二:更新 Webpack 配置(推荐长期解决方案)

如果使用的是 Webpack 5.54.0+ 版本,可以在配置文件中指定新的哈希算法:

javascript
module.exports = {
  output: {
    hashFunction: "sha256" // 或者使用 "xxhash64"
  }
};

xxhash64 是 Webpack 提供的独立于 OpenSSL 的哈希算法,是更可靠的选择。

方案三:修改 package.json 脚本

对于特定框架(如 Laravel Mix、Next.js 或 Vue.js),可以在 package.json 中直接设置环境变量:

json
{
  "scripts": {
    "dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider next dev",
    "build": "NODE_OPTIONS=--openssl-legacy-provider webpack --config webpack.config.js"
  }
}

方案四:降级 Node.js 版本

如果上述方案不可行,可以考虑降级到 Node.js 16 LTS 版本:

bash
nvm install 16.13.0
nvm use 16.13.0
docker
FROM node:16-alpine

Node.js 16 LTS 版本仍然使用 OpenSSL 1.1.x,不会出现此兼容性问题。

方案五:修改 Node.js 加密模块(不推荐)

作为最后的手段,可以临时修改 Node.js 的加密模块:

javascript
const crypto = require("crypto");
const originalCreateHash = crypto.createHash;

crypto.createHash = (algorithm) => 
  originalCreateHash(algorithm === "md4" ? "sha256" : algorithm);

警告

此方案会修改全局加密模块行为,可能会影响其他依赖,请谨慎使用。

解决方案对比

方案适用场景优点缺点
环境变量临时解决方案简单快捷需要每次设置
更新配置Webpack 5.54.0+永久解决需要更新 Webpack
降级 Node.js所有场景稳定可靠使用旧版本 Node.js
修改加密模块紧急修复立即生效可能影响其他功能

总结

ERR_OSSL_EVP_UNSUPPORTED 错误是由于 Node.js 17+ 和 OpenSSL 3.0 不再支持 MD4 算法导致的。推荐按照以下优先级选择解决方案:

  1. 首选:更新 Webpack 配置使用 xxhash64sha256 算法
  2. 临时方案:设置 NODE_OPTIONS=--openssl-legacy-provider 环境变量
  3. 兼容性方案:降级到 Node.js 16 LTS 版本

长期项目应该优先考虑更新 Webpack 配置,而短期或紧急情况可以使用环境变量方案快速解决问题。

提示

随着 Webpack 和 Node.js 的持续更新,这个问题在未来版本中可能会得到根本解决。建议定期检查框架和运行环境的更新日志。