Vite 面试题
基础概念
Vite 是什么?它的核心优势是什么?
Vite 是一个由 Vue.js 作者尤雨溪开发的下一代前端构建工具。
核心优势:
- 极速的开发服务器启动:基于 ES modules,无需打包,启动速度极快
- 快速的热更新(HMR):只更新修改的模块,更新速度与项目大小无关
- 优化的生产构建:使用 esbuild + Rollup,构建速度快
- 开箱即用:内置 TypeScript、JSX、CSS 预处理器支持
- 配置简单:相比 Webpack 配置更简洁
Vite 和 Webpack 的主要区别是什么?
| 特性 | Vite | Webpack |
|---|---|---|
| 开发模式 | 基于 ES modules,无需打包 | 需要打包所有模块 |
| 启动速度 | 毫秒级 | 秒级(项目越大越慢) |
| HMR 速度 | 极快,只更新修改的模块 | 需要重新打包相关模块 |
| 生产构建 | esbuild + Rollup | Babel + Webpack |
| 配置复杂度 | 简单 | 复杂 |
| 生态 | 快速增长 | 成熟稳定 |
Vite 的工作原理是什么?
开发模式:
- 启动开发服务器,不进行打包
- 浏览器直接请求 ES 模块
- 服务器按需编译请求的模块
- 使用 esbuild 进行依赖预构建(CommonJS → ESM)
- HMR 只更新修改的模块
生产模式:
- 使用 Rollup 进行打包
- 使用 esbuild 进行代码转换(比 Babel 快 10-100 倍)
- 代码分割、压缩、Tree Shaking 等优化
为什么 Vite 开发服务器启动这么快?
原因:
- 无需打包:直接使用浏览器原生 ES modules
- 按需编译:只编译请求的模块,不是全部模块
- 依赖预构建:使用 esbuild 预构建依赖(比传统打包工具快)
- 缓存机制:预构建的依赖会被缓存
配置相关
Vite 如何处理环境变量?
使用方式:
- 环境变量必须以
VITE_开头 - 通过
import.meta.env访问 - 支持
.env、.env.development、.env.production等文件
// .env
VITE_API_URL=https://api.example.com
// 使用
const apiUrl = import.meta.env.VITE_API_URL;
Vite 如何配置路径别名?
// vite.config.js
import { resolve } from 'path';
export default defineConfig({
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@components': resolve(__dirname, 'src/components'),
},
},
});
// tsconfig.json 或 jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
Vite 如何配置代理?
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});
性能优化
Vite 如何优化生产构建?
优化策略:
- 代码分割:使用
manualChunks配置 - 依赖预构建:配置
optimizeDeps - 压缩:使用 terser 或 esbuild
- Tree Shaking:自动启用
- 静态资源优化:图片压缩、base64 转换等
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'utils': ['axios', 'lodash'],
},
},
},
},
});
Vite 的依赖预构建是什么?为什么需要?
依赖预构建:
- 将 CommonJS/UMD 格式的依赖转换为 ES modules
- 使用 esbuild 进行转换,速度极快
- 预构建结果会被缓存
为什么需要:
- 浏览器需要 ES modules 格式
- 减少 HTTP 请求数量(合并多个小文件)
- 提升加载性能
配置:
export default defineConfig({
optimizeDeps: {
include: ['vue', 'vue-router'],
exclude: ['some-large-dependency'],
},
});
Vite 如何处理 CSS?
处理方式:
- CSS Modules:自动支持,使用
:module后缀 - CSS 预处理器:内置支持 Sass、Less、Stylus
- PostCSS:自动处理,支持 autoprefixer 等
- CSS 代码分割:自动提取到单独文件
export default defineConfig({
css: {
modules: {
localsConvention: 'camelCase',
},
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`,
},
},
},
});
插件系统
Vite 的插件系统是如何工作的?
插件机制:
- 基于 Rollup 插件接口
- 兼容 Rollup 插件
- 提供 Vite 特有的钩子
常用插件:
@vitejs/plugin-vue:Vue 支持@vitejs/plugin-react:React 支持unplugin-auto-import:自动导入 APIunplugin-vue-components:自动注册组件vite-plugin-compression:Gzip 压缩
如何编写一个 Vite 插件?
export default function myPlugin() {
return {
name: 'my-plugin',
// 插件配置
configResolved(config) {
// 配置解析后
},
// 转换代码
transform(code, id) {
if (id.endsWith('.vue')) {
return code.replace('foo', 'bar');
}
},
// 生成代码
generateBundle(options, bundle) {
// 修改输出文件
},
};
}
开发体验
Vite 的 HMR 原理是什么?
HMR 流程:
- 文件修改后,Vite 检测到变化
- 只重新编译修改的模块
- 通过 WebSocket 通知浏览器
- 浏览器请求更新后的模块
- 替换旧模块,保持应用状态
优势:
- 更新速度与项目大小无关
- 保持应用状态
- 精确到模块级别
Vite 如何处理 TypeScript?
处理方式:
- 开发模式:使用 esbuild 进行类型检查和转换(速度快)
- 生产构建:使用 esbuild 转换,也可以使用 tsc 进行类型检查
- 类型声明:自动生成
.d.ts文件
配置:
// tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"types": ["vite/client"]
}
}
Vite 如何处理静态资源?
处理方式:
- 导入为 URL:
import logo from './logo.png' - 导入为字符串:
import shader from './shader.glsl?raw' - 导入为 Worker:
import Worker from './worker.js?worker' - 内联为 base64:
import logo from './logo.png?inline' - public 目录:直接复制到输出目录
生产构建
Vite 生产构建使用什么工具?
构建工具:
- 代码转换:esbuild(比 Babel 快 10-100 倍)
- 打包:Rollup(Tree Shaking 效果好)
- 压缩:terser 或 esbuild
为什么选择 Rollup:
- Tree Shaking 效果好
- 输出代码质量高
- 适合生产构建
Vite 如何实现代码分割?
方式:
- 动态导入:
import()语法自动分割 - 手动配置:
build.rollupOptions.output.manualChunks
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router'],
'utils': ['axios', 'lodash'],
},
},
},
},
});
Vite 的 Tree Shaking 如何工作?
原理:
- 基于 Rollup 的 Tree Shaking
- 静态分析 ES modules
- 自动移除未使用的代码
条件:
- 使用 ES modules 语法
- 生产模式自动启用
- 确保没有副作用标记
常见问题
Vite 如何处理 CommonJS 模块?
处理方式:
- 依赖预构建:自动将 CommonJS 转换为 ESM
- 使用插件:
@rollup/plugin-commonjs
配置:
export default defineConfig({
optimizeDeps: {
include: ['commonjs-module'],
},
});
Vite 支持多页面应用吗?
支持方式:
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
admin: resolve(__dirname, 'admin.html'),
},
},
},
});
Vite 如何配置库模式?
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MyLib',
fileName: (format) => `my-lib.${format}.js`,
formats: ['es', 'umd', 'cjs'],
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue',
},
},
},
},
});
Vite 和 Create React App / Vue CLI 的区别?
| 特性 | Vite | CRA/Vue CLI |
|---|---|---|
| 开发服务器 | 基于 ES modules | 基于 Webpack |
| 启动速度 | 极快 | 较慢 |
| HMR | 极快 | 较快 |
| 配置 | 简单 | 复杂(需要 eject) |
| 构建工具 | esbuild + Rollup | Webpack |
Vite 的兼容性如何?
浏览器支持:
- 需要支持原生 ES modules 的浏览器
- 现代浏览器都支持(Chrome 61+、Firefox 60+、Safari 11+)
- 旧浏览器需要 polyfill(通过插件)
Node.js 支持:
- 需要 Node.js 14.18+ 或 16+
Vite 如何处理 SSR?
支持方式:
- 使用
vite-plugin-ssr - 或使用框架提供的 SSR 支持(如 Nuxt.js、SvelteKit)
原理:
- 开发模式:支持 HMR
- 生产模式:服务端渲染 + 客户端激活
最佳实践
Vite 项目优化建议
- 使用路径别名:简化导入路径
- 合理配置代码分割:避免单个文件过大
- 使用 CDN:通过
build.rollupOptions.external配置 - 启用压缩:生产环境启用 Gzip/Brotli
- 图片优化:使用
vite-plugin-imagemin - 依赖预构建:合理配置
optimizeDeps
Vite 常见错误及解决方案
问题1:环境变量未定义
- 确保变量以
VITE_开头 - 使用
import.meta.env访问
问题2:路径别名不生效
- 检查
tsconfig.json或jsconfig.json配置 - 确保路径正确
问题3:第三方库兼容性问题
- 添加到
optimizeDeps.include - 或使用相应的插件
问题4:构建后路径错误
- 配置
base选项 - 检查
publicPath配置