Vite 炸裂快,Webpack 稳如山,Turbopack 想两头要:谁才是下一个王?

447 阅读3分钟

你改了一行代码,按下保存。
Vite:100 毫秒内浏览器刷新。
Webpack:要等一秒。

为什么差距这么大?
答案在这行哲学级设计选择里:

“文件变化时,要重新编译多少模块?”

  • Vite:只编译这个文件。
  • Webpack / Turbopack:编译这个文件和它影响到的所有模块

这一个决策,让 Vite 快出一倍,也种下了“偶尔翻车”的种子。

⚙️ Vite 为什么这么快

Vite 的核心是极致的最小编译

  1. 检测到改动 → 只用 esbuild 重编译这一个文件(约 20–30ms)。
  2. 找 HMR 边界(比如 React 组件)。
  3. 通过 WebSocket 通知浏览器:import('/src/xxx?t=时间戳')
  4. React Fast Refresh 替换组件函数,保留 state 并重新渲染。

整个过程通常100ms 内完成,开发者几乎感受不到延迟。

⚡ 这是“即时反馈”体验的关键。

Vite 为什么会“翻车”

Vite 快,是因为它只替换组件函数,不会重新执行模块顶层代码。
但正是这点,导致某些情况出错或不一致。

1. 模块顶层常量不更新

export const THEME = 'dark';
const currentTheme = themeMap[THEME]; // 只计算一次

改成 'light' 后,组件渲染新主题,但 currentTheme 依然是旧值。

2. 顶层实例不重建

const store = new Store();

改了 Store 的逻辑,实例还在旧的内存里,不会重建。

3. 副作用重复或缺失

console.log('init');
window.initSomething();

模块被重复执行时,副作用代码可能被多次调用,产生混乱。

4. 循环依赖

A 导入 B,B 又导入 A。Vite 会放弃 HMR,触发整页刷新。

这些问题都源于:模块没重新执行
Vite 的成功率在实践中大约 90–95%

Webpack 的思路:稳中求全

Webpack 在 HMR 时,不仅编译变动的模块,还会编译所有受影响的依赖链,确保顶层逻辑重新执行。

优点:一致性高,不会出现“变量更新了但模块没重跑”的错乱。
缺点:慢。

  • 依赖分析:50ms
  • 多模块重编译:300ms
  • 推送更新 + 执行:150ms
  • 总计约 500ms

成功率约 97–99% ,但牺牲了灵敏度。

Webpack 的哲学是“宁慢勿错”,保证行为一致。

Turbopack:两边都要的野心家

Next.js 团队的 Turbopack 想在Vite 的速度Webpack 的可靠性之间找平衡。

  • 使用 Rust 编译管线,极快的增量编译。
  • 增量图更新 + 响应式依赖追踪机制(动态重计算受影响的子图)。
  • 成功率接近 Webpack,但速度明显更快。

实测数据:

工具平均更新时间成功率特点
Vite≈100ms90–95%极速反馈,偶尔翻车
Webpack≈500ms97–99%稳定保守,延迟明显
Turbopack≈200ms96–99%速度稳定兼顾,未来之选

Turbopack 的哲学是“用增量计算保障正确性”,
目标是在大型项目中维持接近 Vite 的体验,又避免状态不一致。

如何写出不容易“翻车”的 Vite 代码

Vite 快速没问题,关键是你别坑自己。

1. 状态放组件,不放模块顶层

// ❌
const store = new Store();

// ✅
export function App() {
  const [store] = useState(() => new Store());
}

2. 导出对象而不是常量

// ❌
export const MAX_COUNT = 10;

// ✅
export const config = { MAX_COUNT: 10 };
if (import.meta.hot) {
  import.meta.hot.accept(newModule => Object.assign(config, newModule.config));
}

3. 避免模块顶层副作用

// ❌
window.initAnalytics();

// ✅
export function initAnalytics() {
  window.initAnalytics();
}

4. 用函数返回动态值

// ❌
export const theme = themeConfig[THEME];

// ✅
export function getTheme() {
  return themeConfig[THEME];
}

这些习惯能让 Vite 的 HMR 稳定性接近 Turbopack 水平。

结论

Vite 就像一辆赛车:快得离谱,但需要会开。
Webpack 像老式坦克:笨重,却从不出事。
Turbopack 则在造一辆装了防撞系统的超跑

你想要速度、稳定,还是两者兼得?
选谁,其实就是选择开发体验的哲学。