该错误源于node.js v17+内置openssl 3.0默认禁用旧加密算法,而webpack 4、vue-cli 3等老构建工具仍调用md5等被弃用算法,导致vscode中启动的node进程触发unsupported报错。

VSCode 里跑 Node.js 项目时遇到 error:0308010C:digital envelope routines::unsupported,不是你的代码错了,也不是 VSCode 本身有问题——是 Node.js 进程在 VSCode 启动的上下文中,调用加密算法时被 OpenSSL 3.0 拦住了。根本矛盾在于:项目(尤其是老构建工具如 webpack 4、vue-cli 3、create-react-app
为什么在 VSCode 终端里 node --version 显示 v20.x,却还是报错?
因为版本号只是表象,真正起作用的是 Node.js 启动时加载的 OpenSSL 提供者(provider)。v17+ 的 Node.js 默认只加载 default provider,不加载 legacy;而老项目构建脚本(比如 vue-cli-service serve)内部调用 crypto.createHash('md4') 这类操作时,OpenSSL 3.0 直接拒绝,不抛详细堆栈,只甩出那个 cryptic 错误。
- VSCode 终端是否继承了你 shell 的环境变量(比如
NODE_OPTIONS),取决于它怎么启动:从 Dock/macOS Finder 或 Windows 开始菜单启动的 VSCode,不会自动读取 ~/.zshrc 或 ~/.bashrc 中的 export 设置 - 即使你在系统终端里执行过
export NODE_OPTIONS=--openssl-legacy-provider,VSCode 主进程已缓存旧环境,重启前无效 -
process.versions.openssl在 VSCode 终端里打印出来是 3.0.x,但没告诉你当前生效的是哪个 provider —— 你需要实际运行一段 crypto 代码才能验证
在 VSCode 里让 NODE_OPTIONS 真正生效的三种方式
不能只靠改系统环境变量,得让 VSCode 的子进程(终端、调试器)明确带上这个 flag:
微软正式发布 Visual Studio Code 1.118 版本 。本次更新重点强化了 AI 开发体验与企业管理能力,其中最引人注目的是新增 Copilot CLI 远程控制功能,允许开发者通过手机或网页远程监控和接管 AI 会话 。同时,为了提高 AI 的运行性价比,新版本优化了令牌缓存策略以降低成本 。此外,1.118 版还引入了 Chronicle 本地历史追踪、TypeScript 7.0 支持以及更严格的企业级访问管控 。
-
终端启动前重载环境:按
Ctrl+Shift+P(Win/Linux)或Cmd+Shift+P(macOS),输入Terminal: Reload Shell Environment并执行;之后新开终端,echo $NODE_OPTIONS应该输出--openssl-legacy-provider -
调试器 launch.json 强制注入:在
.vscode/launch.json的配置中加入"env": {"NODE_OPTIONS": "--openssl-legacy-provider"},这对node调试会话有效,但不影响终端或扩展主机 -
全局设置(谨慎):在 VSCode 设置里搜
terminal.integrated.env,为对应平台添加:"terminal.integrated.env.linux": {"NODE_OPTIONS": "--openssl-legacy-provider"}(Windows/macOS 同理)。注意:这会影响所有终端会话,包括 npm script、git hook 等
npm run dev 报错但 node -e "require('crypto').createHash('md4')" 却不报?
这是最典型的误导现象——你手动测试的是 Node.js 运行时本身支持 legacy provider,但项目启动链路更长:比如 vue-cli-service 是一个 shell wrapper,它可能通过 #!/usr/bin/env node 启动,绕过了你设的 NODE_OPTIONS;或者它内部 spawn 了子进程,而子进程不继承父进程的 NODE_OPTIONS。
- 验证方式:在项目根目录下直接运行
node --openssl-legacy-provider node_modules/.bin/vue-cli-service serve,如果成功,说明问题出在启动脚本未透传环境变量 - 常见于 pnpm/yarn 项目:包管理器的
bin解析机制可能截断环境变量传递,此时必须在package.json的 script 里显式写死:"dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve"(Linux/macOS)或"dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve"(Windows cmd) - Webpack 4 用户注意:
webpack --watch也会触发该错误,且无法通过 loader 配置绕过,必须从启动层解决
最容易被忽略的一点:这个错误从来不是“Node.js 版本太高”,而是“加密调用路径没走通 legacy provider”。哪怕你降级到 Node.js v16,只要某处代码显式调用了 crypto.setEngine 或某些 C++ 插件硬编码了 provider 名称,照样会崩。所以优先 fix 环境变量透传,而不是盲目换 Node 版本。










