确实有可能出现标题的情况,但是原因不是 Vite 或者 Webpack ,而是它们默认的 TypeScript 处理方式不同。
Vite:默认不会做 TypeScript 类型检查
Vite 默认使用的是 esbuild 来处理 ts,而 esbuild 只做:
TS → JS 转换(去掉类型),不检查类型
例如:
js
let a: string = 123;
console.log(a);
执行:
js
esbuild
↓
去掉类型
↓
let a = 123;
console.log(a);
浏览器完全可以运行,但是编辑器会有一些红色波浪线提示 Type 'number' is not assignable to type 'string'

Webpack 为什么经常不行?
其实 Webpack 本身也不会检查 TS,关键在于你用了什么 Loader。
ts-loader
js
{
test: /.ts$/,
loader: "ts-loader"
}
ts-loader 会执行:
js
tsc
↓
检查类型
↓
有错误
↓
停止编译
所以会报错,导致项目启动不了。
js
TS Error
↓
webpack compile failed
如果 ts-loader 开启 transpileOnly
js
{
loader: "ts-loader",
options: {
transpileOnly: true
}
}
它也会变成:
只转 JS,不检查类型
Babel Loader
但有些 Webpack 项目可能不是使用的 ts-loader,而是用的 Babel Loader,其执行过程是:
js
ts
↓
babel-loader
↓
@babel/preset-typescript
Babel Loader 也不会检查类型,其只会:
删除类型,生成 JS
例如:
js
let a: string = 123;
直接变成
js
let a = 123;
Babel + TypeScript 和 Vite + esbuild 的行为基本一致。
真正负责检查 TS 的是谁?
其实一直都是 tsc
也就是
js
npx tsc --noEmit
或者
npx vue-tsc --noEmit
例如:
json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"type-check": "vue-tsc --noEmit"
}
}
开发时:
js
vite
↓
快速启动
↓
不检查 TS
提交代码前:
js
npm run type-check
发现所有类型错误。
为什么 Vite 要这样设计?
因为 TypeScript 类型检查很慢,例如一个大型项目:
js
tsc
需要 10~20 秒
而 esbuild:
js
几十毫秒
Vite 的理念就是 ------ 把两件事情拆开:
js
开发:
esbuild
↓↓
极速启动
类型检查:
tsc / vue-tsc
↓↓
单独执行
Webpack 以前为什么喜欢一起检查?
早期的 Webpack 项目一般都是 ------ 所有事情放在一次编译里:
js
webpack
│
├── ts-loader
│ │
│ ├── 类型检查
│ └── 转 JS
│
└── bundle
优点:
- 编译成功 == 类型没问题。
缺点:
- 很慢。
- 改一行代码也要重新检查整个工程。
现在 Webpack 项目也越来越像 Vite
很多大型项目现在都会这样配置:
js
webpack
│
├── babel-loader
│
└── fork-ts-checker-webpack-plugin
│
└── 单独线程检查 TS
或者:
js
webpack
↓
babel
↓
立即启动
后台
↓
fork-ts-checker-webpack-plugin
或者
CI
↓
tsc --noEmit
也就是说:
现代 Webpack 项目和 Vite 的思路已经越来越接近:编译与类型检查解耦。
总结
| 方案 | 是否检查 TS 类型 | 遇到类型错误是否阻止运行 |
|---|---|---|
| Vite(默认 esbuild) | ❌ 不检查 | ❌ 不阻止,仍可运行 |
| Webpack + ts-loader(默认) | ✅ 检查 | ✅ 通常会阻止编译 |
Webpack + ts-loader(transpileOnly: true) |
❌ 不检查 | ❌ 不阻止 |
| Webpack + babel-loader | ❌ 不检查 | ❌ 不阻止 |
tsc / vue-tsc |
✅ 检查 | ✅ 会报告所有类型错误(通常作为独立步骤或 CI) |
所以这个差异,本质上不是 Vite 和 Webpack 的区别 ,而是项目采用的 TypeScript 编译链路不同导致。