正文

升级 Vite 7 时,很多项目不是卡在 React、Vue、Svelte 或 TypeScript,而是卡在一行看似普通的版本报错上:

有些团队更困惑:我已经是 Node 20 了,为什么 20.18 还不行?我已经是 Node 22 了,为什么 22.11 也不行?

答案不只是“Vite 变严格了”。真正原因是:Vite 7 正式进入更彻底的 ESM-only 发布阶段,而它需要 Node.js 对 require(esm) 的无 flag 支持。 Vite 官方在 Vite 7 发布说明中明确写到,Vite 7 现在要求 Node.js 20.19+22.12+,并且放弃了 Node.js 18,因为 Node 18 已经进入 EOL;同时,这些版本范围能让 Node.js 在不加实验 flag 的情况下支持 require(esm),从而允许 Vite 7 以 ESM-only 形式发布,但又不阻断 CommonJS 模块通过 Vite JavaScript API 使用它。

Bash
You are using Node.js 18.x.x.
Vite requires Node.js version 20.19+ or 22.12+.
Please upgrade your Node.js version.

Vite 7 为什么突然要求 Node 20.19+ / 22.12+?

先说结论:不是所有 Node 20 都能满足 Vite 7,也不是所有 Node 22 都能满足 Vite 7。

Vite 7 的 Node 版本要求是:

Vite 官方仓库的 package.json 中也能看到这个 engines.node 范围。

这意味着:

所以,升级卡住的核心不是“Node 主版本太低”,而是小版本刚好差一点

Node 18.x不适合
Node 20.18.x不适合
Node 20.19.x适合
Node 22.11.x不适合
Node 22.12.x+适合
Node 24.x通常适合
JSON
{
  "node": "^20.19.0 || >=22.12.0"
}

真正的关键:require(esm) 是什么?

过去 JavaScript 工具链长期存在两套模块系统:

现代前端生态越来越偏向 ESM。Vite 本身也一直是推动 ESM 开发体验的重要工具。但现实问题是:很多旧插件、脚本、配置工具、测试工具,仍然运行在 CommonJS 环境中。

这就带来一个痛点:如果 Vite 只发布 ESM,CommonJS 项目还能不能 require('vite')

在较旧的 Node.js 中,CommonJS 直接 require() 一个原生 ES Module,经常会遇到类似 ERR_REQUIRE_ESM 的问题。Node 20.19.0 的发布说明指出,require(esm) 在 Node 20.x 中已默认启用,不再需要 --experimental-require-module;启用后,Node.js 使用 require() 加载 ES Module 时不再抛出 ERR_REQUIRE_ESM,但如果被加载的 ES Module 或依赖中包含 top-level await,仍可能抛出 ERR_REQUIRE_ASYNC_MODULE

Node 22.12.0 也做了同类变化:require(esm) 在 Node 22.x 中不再需要实验 flag,并且 Node 文档说明可以通过 process.features.require_module 检查当前 Node 实例是否支持该能力。

这就是 Vite 7 要求 Node 20.19+ / 22.12+ 的真正原因。

它不是随便卡版本,而是为了确保运行时具备关键模块能力。

js
// CommonJS
const vite = require('vite')
js
// ESM
import { createServer } from 'vite'

为什么 Node 20.18 不行?只差 0.01 也不行吗?

是的,不行。

Node 20.19.0 是一个很特殊的小版本。Node 官方说明,虽然 Node 20 当时已经处于维护模式,通常只预期发布 patch,但因为 require(esm) 对生态影响很大,Node 团队特意把这个能力回移到了 20.19.0。

换句话说:

这也是很多人卡住的地方。大家以为“我已经是 Node 20 LTS,应该没问题”,但 Vite 7 看的不是“20”这个大版本,而是20.19.0 这个关键分界线

Bash
Node 20.18.x 没有默认可用的 require(esm)
Node 20.19.x 有默认可用的 require(esm)

为什么 Node 22.11 也不行?

原因类似。

Node 22.12.0 的发布说明写明,require(esm) 在该版本中不再需要 --experimental-require-module flag。

所以:

很多部署平台、CI 镜像、旧 Docker 镜像会默认给你 Node 22,但不一定是 22.12+。这时本地能跑,线上构建却失败,或者本地失败、CI 成功,都是很常见的情况。

Bash
Node 22.11.x 低于 Vite 7 要求
Node 22.12.x 满足 Vite 7 要求

Node 18 为什么被 Vite 7 放弃?

Vite 7 放弃 Node 18,既是技术选择,也是生态周期选择。

Vite 7 迁移指南明确写到:Vite 不再支持已经 EOL 的 Node.js 18,现在要求 Node.js 20.19+ / 22.12+

Node 官方也说明,当一个 Node 主版本进入 EOL 后,就不再接收更新,包括安全补丁;这会带来安全风险、工具链破损、生态漂移和合规问题。

所以对 Vite 来说,继续支持 Node 18 意味着:

而前端工具链的趋势很明显:新版本工具会更快放弃 EOL Node,转向更新的运行时能力。

  • 要继续照顾旧模块系统边界。
  • 要保留更多兼容代码。
  • 要增加维护成本。
  • 要拖慢 ESM-only 生态迁移。

常见报错不一定只有一种

升级 Vite 7 后,常见错误可能包括:

也可能是:

还可能是某些间接依赖先把 Vite 7 拉进来了,导致你明明没主动升级 Vite,却突然安装失败。

这通常发生在:

  • 框架升级,例如 React Router、SvelteKit、Astro、Storybook、Vitest 等依赖 Vite 的工具。
  • 包管理器更新 lockfile。
  • CI 使用了不同 Node 版本。
  • Docker 镜像还停在 node:20.18node:22.11
  • 本地终端和 IDE 内置终端使用了不同 Node。
Bash
Vite requires Node.js version 20.19+ or 22.12+
Bash
error vite@7.x.x: The engine "node" is incompatible with this module.
Expected version "^20.19.0 || >=22.12.0".

升级前先查四个地方

1. 查本地 Node 版本

推荐结果至少是: 或: 如果你正在新建项目,Vite 官方 Getting Started 页面也明确提示:Vite 需要 Node.js 20.19+22.12+,部分模板还可能要求更高版本。

2. 查包管理器实际使用的 Node

有时 node -v 是新的,但 npmpnpmyarn、IDE、脚本环境仍在用旧 Node。 可以分别检查: Windows PowerShell 可以用: 如果路径指向旧安装目录,就说明你的系统 PATH、nvm、fnm、Volta 或 IDE 配置没有统一。

3. 查 CI/CD Node 版本

GitHub Actions 示例: 或者更推荐写成: 但要注意,使用大版本号时,CI 通常会拉该大版本的较新 release;如果企业内网镜像或缓存较旧,仍建议锁定到明确版本。

4. 查 Docker 镜像

很多项目会这样写: 这通常没问题,但如果你锁得太死: 那升级 Vite 7 就会失败。 更安全的写法: 或: 如果你希望构建长期稳定,建议团队统一选择 Node 22 LTS 或更高的稳定 LTS,并在本地、CI、Docker、部署平台保持一致。Node 官方发布列表显示,截至当前资料,Node 22 与 Node 24 均处于 LTS 状态,而 Node 20 已进入 EOL。

Bash
node -v
Bash
v20.19.0
Bash
v22.12.0
Bash
node -v
npm -v
pnpm -v
yarn -v
which node
which npm
PowerShell
Get-Command node
Get-Command npm
YAML
- uses: actions/setup-node@v4
  with:
    node-version: 22.12.0
YAML
- uses: actions/setup-node@v4
  with:
    node-version: 22
dockerfile
FROM node:20
dockerfile
FROM node:20.18
dockerfile
FROM node:22.12-alpine
dockerfile
FROM node:22-alpine

推荐解决方案:不要只升级本机,要统一全链路

只在自己电脑上执行:

只能解决本地问题,不能解决团队问题。

更完整的做法是把 Node 版本写进项目配置。

使用 .nvmrc

然后团队成员运行:

使用 .node-version

适合 fnm、asdf、mise 等工具。

在 package.json 中声明 engines

如果你想更强制,可以在 .npmrc 中加入: 这样版本不对时会尽早失败,而不是等到构建或部署阶段才炸。

Bash
nvm install 22
nvm use 22
txt
22.12.0
Bash
nvm install
nvm use
txt
22.12.0
JSON
{
  "engines": {
    "node": "^20.19.0 || >=22.12.0"
  }
}
ini
engine-strict=true

Vite 7 升级不只是 Node:还要顺手检查这些变化

虽然这篇文章重点讲 Node 版本,但 Vite 7 还有其他升级点。

Vite 7 迁移指南提到,默认浏览器构建目标从旧的 'modules' 改为 'baseline-widely-available',对应的默认浏览器版本也更新为 Chrome 107、Edge 107、Firefox 104、Safari 16.0。

此外,Vite 7 还移除了 Sass legacy API 支持,并清理了一些废弃特性,例如 splitVendorChunkPlugin、旧的 transformIndexHtml hook 写法等。

所以,升级顺序建议是:

如果你使用 npm:

如果你使用 yarn:

Bash
node -v
pnpm why vite
pnpm up vite
pnpm install
pnpm build
pnpm test
Bash
npm ls vite
npm install vite@latest
npm run build
npm test
Bash
yarn why vite
yarn add vite@latest
yarn build
yarn test

实战排查清单

本地 Node使用 `node -v` 确认至少是 20.19 或 22.12
包管理器确认 npm/pnpm/yarn 没有调用旧 Node
IDE 终端检查 VS Code、WebStorm 是否使用同一 Node
CI显式配置 Node 22.12+
Docker不要使用 `node:20.18`、`node:22.11` 这类旧镜像
部署平台检查平台默认 Node,而不是只看本地
lockfile升级后重新安装依赖并提交 lockfile
间接依赖检查是否由框架或测试工具间接引入 Vite 7

FAQ:Vite 7 和 Node 版本常见问题

1. Vite 7 必须用 Node 22 吗?

不必须。Vite 7 支持 Node 20.19+22.12+。不过从长期维护角度看,Node 22 或更新 LTS 通常更适合作为新项目和团队升级目标。

2. Node 20.18 为什么不行?

因为 Vite 7 需要 Node 默认支持 require(esm),而 Node 20.19.0 才把这个能力默认启用并回移到 Node 20.x。

3. Node 22.11 为什么不行?

因为 Node 22.12.0 才取消了 require(esm) 对实验 flag 的依赖。低于 22.12 的版本不满足 Vite 7 的运行时要求。

4. Node 18 还能强行跑 Vite 7 吗?

不建议,也不应作为正式方案。Vite 7 官方已经不支持 Node 18,而 Node 官方也说明 EOL 版本不会继续获得安全补丁和维护。

5. 为什么我本地是 Node 22,Vite 还说我是 Node 18?

通常是 PATH、nvm、fnm、Volta、IDE 终端、全局 npm 路径或 CI 缓存不一致。请同时检查 node -vwhich nodenpm config get prefix,以及 IDE 和构建脚本实际使用的 shell。

6. 升级 Node 后需要删除 node_modules 吗?

建议删除后重新安装,尤其是项目依赖中有 native 模块、锁文件长期未更新,或者本地和 CI 表现不一致时: pnpm 项目可以执行: 不过团队项目中删除 lockfile 要谨慎,最好在升级分支中统一处理。

Bash
rm -rf node_modules package-lock.json
npm install
Bash
rm -rf node_modules pnpm-lock.yaml
pnpm install

结论:Vite 7 卡住,不是版本刁难,而是生态转向 ESM 的信号

《Vite 7 升级卡住:为什么要求 Node 20.19+ / 22.12+》这个问题的核心答案是:Vite 7 要以 ESM-only 方式发布,同时仍要尽量兼容 CommonJS 调用场景,因此它需要 Node.js 默认支持 require(esm)

Node 20.19 和 Node 22.12 正好是关键分界线。低于这个版本,即使只是差一个小版本,也可能不满足 Vite 7 的底层运行条件。

所以,正确的升级姿势不是只改 vite 版本,而是统一升级整条链路:

把这些地方统一到 Node 22.12+ 或更新 LTS 后,Vite 7 升级通常会顺畅很多。对团队来说,这次升级也不是单纯修一个报错,而是一次把前端工程基础设施拉回现代 ESM 生态的好机会。

Bash
本地 Node
包管理器
CI/CD
Docker 镜像
部署平台
团队版本管理文件

参考来源

Vite 7.0 is outVite BlogVite package.jsonGitHubNode.js 20.19.0 LTS releaseNode.js BlogNode.js 22.12.0 LTS releaseNode.js BlogMigration from v6Vite 7 DocsNode.js End-Of-LifeNode.jsGetting StartedVite DocsNode.js ReleasesNode.js

相关文章

Nuxt 4 升级前先查什么:目录结构、useFetch、TypeScript 和模块兼容性工程实践 / 约 16 分钟Claude Code 项目上下文怎么检查开发环境 / 约 11 分钟7 个关键洞察:AI Coding 工具真正改变的不是写代码,而是验证代码智能编程 / 约 18 分钟AI Agent 让你安装依赖时,哪些包不能直接允许智能编程 / 约 12 分钟