构建工具与 Vite
浏览器要的是 一组可缓存的静态文件(JS/CSS/图);你写的是模块化源码、JSX、TypeScript。构建工具负责转译、拼图、在开发时提供热更新。模块语义见 模块系统;产物策略见 产物与代码分割。TS 与打包器分工见 配置与工程实践。
当下全栈前端默认假设:开发用 Vite,生产仍由 Vite 调 Rollup(或 Rolldown 一类打包器)出包。 Webpack 仍大量存在于存量项目,先认现场再谈迁移。
解决什么问题
| 痛点 | 构建工具怎么帮 |
|---|---|
浏览器不懂 TSX / .ts | 转译(esbuild / swc / Babel) |
几百个 import 不能全当 HTTP 瀑布 | 开发:原生 ESM + 预构建;生产:打包成 chunk |
| 改一行等几十秒 | 开发不打包整站,按需编译 + HMR |
| 类型过了但线上语法太新 | target / 浏览器列表;转译与 tsc 检查是两件事 |
一句话:开发求快,走原生 ESM;生产求少请求、可缓存,走打包。
先认现场
| 标志 | 含义 |
|---|---|
vite.config.ts | Vite 项目 |
webpack.config.js / rsbuild.config.* | Webpack 系 / Rsbuild |
只有 tsc 没有打包配置 | 可能是纯 Node 库,不是前端应用 |
next.config.* | Next 自带编译,不要再套一层 Vite 打同一应用 |
命令以 package.json 的 scripts 为准:常见 dev / build / preview。
Vite 开发为什么快
浏览器
│ import /src/main.tsx
▼
Vite 开发服务器 ─ 按需转译单文件(esbuild)
│
├─ 源码:原生 ESM,改谁编译谁
└─ 依赖:预构建进 node_modules/.vite(esbuild 打成少数 ESM)
第三方包(尤其是 CJS)直接给浏览器会很慢或根本不能跑,所以 dep prebundle:第一次 vite 时把 node_modules 里用到的依赖转成 ESM 并缓存。依赖没变就复用缓存。
生产 vite build:用打包器做 tree-shaking、分割、压缩,输出 dist/。
最小配置直觉
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: { port: 5173, proxy: { "/api": "http://localhost:8080" } },
build: { outDir: "dist", sourcemap: true },
});
| 项 | 作用 |
|---|---|
| plugin | 框架(React/Vue)、SVGR、可视化检查器等 |
server.proxy | 开发期绕开跨域,把 /api 转到后端 |
resolve.alias | @/ 路径;要与 tsconfig paths 对齐 |
envPrefix / .env | 见 多环境发布 |
HMR:插件把模块边界告诉客户端,尽量只换模块而不是整页刷新。状态能不能保住取决于框架插件,不是 Vite 核心保证。
和 tsc / Webpack 怎么分工
| 工具 | 典型职责 |
|---|---|
| Vite 开发 | 转译 + ESM 服务 + HMR |
| Vite build | 生产打包 |
tsc --noEmit | 类型检查(CI 必跑) |
| Webpack | 存量:loader/plugin 生态、Module Federation 等 |
Vite 转译 擦类型、不保证类型正确。打包绿了不等于类型绿了。
Webpack 面试对照(不必开新项目学一遍):
- Webpack:一切皆模块,依赖图 + loader 转译 + plugin 钩生命周期;开发也常打包,所以冷启动慢
- Vite:开发不打包应用源码;生产才打包
Rsbuild / Farm / Rolldown 都在「更快的打包」赛道,概念仍是 图 + 转译 + 产物。
排障口令
| 现象 | 先看 |
|---|---|
| 开发正常、build 挂 | 只在 import.meta.env.DEV 里的代码、CJS/ESM 混用、顶层 await |
| 改了依赖没生效 | 清 node_modules/.vite,重启 dev |
| alias 能编译、IDE 报红 | tsconfig paths 没对齐 |
| 代理 404 | proxy 路径前缀与后端路由不一致 |
要点
- 先认
vite.config还是webpack.config,跟仓库脚本走 - Vite 快在「开发不打包源码 + 依赖预构建」
- 转译 ≠ 类型检查
- 生产产物策略下一篇;本篇只把工具链边界划清
- 代理只解决开发跨域,生产要网关或同源部署
面试速记
- Vite 和 Webpack 最大差别? 开发期 Vite 用原生 ESM 按需编译;Webpack 传统上开发也打包整图。
- 为什么要依赖预构建?
node_modules里大量 CJS / 细碎模块,预打成 ESM 才能给浏览器高效加载。 - 为什么还要跑
tsc? Vite 不管类型正确性。 - HMR 是什么? 用新模块替换旧模块,尽量避免整页刷新。
preview干什么? 本地以生产产物起静态服务,用来验证 build,不是开发 HMR。