1. Vite 是什么?有什么特点?
// Vite 的主要特点:
1. 开发服务器启动快(基于 ESM)
2. 热更新快(基于 ESM)
3. 按需编译
4. 内置对 TypeScript、JSX、CSS 等的支持
2. Vite 和 Webpack 的区别
// Vite
- 开发环境下不打包,基于 ESM
- 生产环境使用 Rollup 打包
- 冷启动更快
- 热更新更快
// Webpack
- 开发环境下打包
- 全环境都需要打包
- 配置更灵活
- 生态更完善
3. Vite 的基本配置
// vite.config.js
// 1. 导入必要的模块
import { defineConfig } from 'vite' // 导入 vite 配置函数,提供类型提示
import vue from '@vitejs/plugin-vue' // 导入 vue 插件,用于处理 .vue 文件
export default defineConfig({
// 2. 开发服务器配置
server: {
port: 3000, // 设置开发服务器端口号为 3000
proxy: { // 设置代理,用于解决跨域问题
'/api': { // 当请求路径以 /api 开头时进行代理
target: 'http://example.com', // 代理目标地址
changeOrigin: true // 修改请求头中的 Origin,解决跨域问题
}
}
},
// 3. 构建配置
build: {
outDir: 'dist', // 指定构建输出目录
minify: 'terser' // 使用 terser 进行代码压缩(比 esbuild 压缩更彻底)
},
// 4. 插件配置
plugins: [
vue() // 使用 vue 插件,使 vite 能够处理 .vue 文件
],
// 5. 路径解析配置
resolve: {
alias: {
'@': '/src' // 设置路径别名,@ 符号指向 src 目录,方便导入文件
}
}
})
4. Vite 的插件机制
// 自定义插件示例
export default function myPlugin() {
// 返回一个插件对象
return {
// 插件名称,必须的属性,用于识别插件
name: 'my-plugin',
// buildStart 钩子:在构建开始时触发
buildStart() {
console.log('构建开始')
// 这里可以做一些构建前的准备工作
// 比如:创建目录、清理缓存等
},
// transform 钩子:用于转换代码
// code: 源代码内容
// id: 文件路径
transform(code, id) {
// 判断是否是 .vue 文件
if (id.endsWith('.vue')) {
// 返回转换后的代码
return transformedCode // 这里的 transformedCode 需要自己实现转换逻辑
}
}
}
}
使用示例:
// vite.config.js
import myPlugin from './my-plugin'
export default defineConfig({
plugins: [
myPlugin()
]
})
5. Vite 的环境变量处理
// .env
VITE_API_URL=http://api.example.com
// .env.development
VITE_API_URL=http://dev-api.example.com
// 使用环境变量
console.log(import.meta.env.VITE_API_URL)
6. Vite 的 CSS 处理
// vite.config.js
export default defineConfig({
css: {
// CSS 预处理器配置
preprocessorOptions: {
scss: {
// 自动导入全局 SCSS 变量文件
// 这样在每个组件中都可以直接使用这些变量,而不需要手动导入
additionalData: `@import "@/styles/variables.scss";`
}
},
// CSS 模块化配置
modules: {
// 配置 CSS 模块的作用域行为
scopeBehaviour: 'local', // 'local' 表示启用局部作用域
// 配置生成的类名格式
localsConvention: 'camelCase' // 将类名转换为驼峰命名
// 例如:.my-class 在 JavaScript 中可以通过 styles.myClass 访问
}
}
})
主要功能:
- CSS 预处理器配置
-
配置 SCSS 预处理器
-
通过
additionalData
自动注入全局 SCSS 变量 -
避免在每个组件中重复导入变量文件
- CSS 模块化配置
-
启用 CSS 模块的局部作用域
-
配置类名的生成规则
-
支持驼峰命名方式访问类名
// @/styles/variables.scss
$primary-color: #1890ff;
$font-size: 14px;
// 组件中使用
<style lang="scss" module>
.myButton {
// 可以直接使用 variables.scss 中的变量
color: $primary-color;
font-size: $font-size;
}
</style>
// 在 JavaScript 中使用
import styles from './style.module.scss'
// 可以通过 styles.myButton 访问类名
7. Vite 的构建优化
// vite.config.js
export default defineConfig({
build: {
// 1. Rollup 打包分块策略配置
rollupOptions: {
output: {
manualChunks: {
// 将 vue 相关的库打包到 vendor 块中
vendor: ['vue', 'vue-router'],
// 将 lodash-es 打包到 utils 块中
utils: ['lodash-es']
}
}
},
// 2. 代码压缩配置
minify: 'terser', // 使用 terser 作为压缩器
terserOptions: { // terser 的具体配置
compress: {
drop_console: true // 删除代码中的 console.log 语句
}
}
}
})
主要功能:
-
代码分块配置 (Code Splitting)
-
使用
manualChunks
手动指定代码分块 -
vendor
块包含 Vue 核心库和路由 -
utils
块包含工具库 -
这样可以更好地利用浏览器缓存,提高加载性能
-
-
代码压缩配置
-
使用
terser
进行代码压缩 -
配置
terser
删除所有console.log
语句 -
减小最终代码体积,提高生产环境性能
-
实际效果:
-
生成的 dist 目录会包含多个 JS 文件:
-
vendor.[hash].js
(Vue 相关代码) -
utils.[hash].js
(工具库代码) -
其他业务代码文件
-
-
生产环境代码中不会有 console.log 语句
这种配置适合需要优化加载性能的中大型项目。
8. Vite 的静态资源处理
// 1. 不同类型的资源导入方式
// 图片导入 - 会被优化处理
import img from './img.png' // 返回处理后的图片 URL
// URL 导入 - 直接获取文件 URL,不做处理
import url from './file.pdf?url' // 添加 ?url 后缀表示直接获取 URL
// 原始内容导入 - 获取文件的原始内容
import text from './file.txt?raw' // 添加 ?raw 后缀表示获取原始内容
// 2. Vite 配置
export default defineConfig({
// 配置额外的静态资源类型
assetsInclude: ['**/*.gltf'], // 将 .gltf 文件作为静态资源处理
build: {
// 小于 4kb 的资源将被转为 base64 内联
assetsInlineLimit: 4096 // 单位为字节(byte)
}
})
主要功能:
- 资源导入方式
-
普通导入:自动优化和处理资源
-
URL 导入
:直接获取资源 URL -
原始导入:获取资源的原始内容
- 资源处理配置
-
assetsInclude
:指定额外的静态资源类型 -
assetsInlineLimit
:控制资源内联的大小阈值
使用示例:
// 在组件中使用
export default {
setup() {
return {
// 使用导入的资源
image: img, // 图片 URL
pdfUrl: url, // PDF 文件 URL
content: text // 文本内容
}
}
}
9. Vite 的 HMR(热更新)
// 自定义 HMR 处理
if (import.meta.hot) { // 检查是否支持热更新
// accept 方法:接受模块更新
import.meta.hot.accept((newModule) => {
// newModule 是更新后的模块
// 这里可以处理模块更新后的逻辑
// 例如:更新组件、重新渲染等
})
// dispose 方法:模块被替换前的清理
import.meta.hot.dispose(() => {
// 在模块被替换前执行清理工作
// 例如:
// - 移除事件监听器
// - 清除定时器
// - 清理缓存
// - 断开 WebSocket 连接等
})
}
具体使用示例:
// 计数器组件示例
let count = 0
const counter = document.getElementById('counter')
// 更新显示
const updateCounter = () => {
counter.textContent = count
}
if (import.meta.hot) {
// 当模块更新时
import.meta.hot.accept((newModule) => {
// 保持状态,使用新的逻辑
count = newModule.count
updateCounter()
})
// 模块卸载前清理
import.meta.hot.dispose(() => {
// 清理可能的副作用
counter.remove()
})
}
主要功能:
-
热更新检测
-
if (import.meta.hot)
检查环境是否支持热更新 -
通常在开发环境中可用
-
-
更新处理
-
accept
方法处理模块更新 -
可以保持应用状态
-
实现平滑更新
-
-
清理工作
-
dispose
方法在模块替换前执行清理 -
防止内存泄漏
-
确保应用状态的正确性
-
这种机制可以在开发时实现代码更新而无需刷新整个页面,提高开发效率。
10. Vite 的性能优化
1. 依赖预构建配置
export default defineConfig({
optimizeDeps: {
// 指定需要预构建的依赖
include: [
'lodash-es', // 预构建 lodash-es
'vue' // 预构建 vue
]
}
})
作用说明:
-
将 CommonJS/UMD 转换为 ESM 格式
-
将有许多内部模块的依赖关系转换为单个模块
-
提高开发服务器的页面加载速度
2. 生产环境优化配置
export default defineConfig({
build: {
target: 'es2015', // 设置目标浏览器的 JavaScript 版本
minify: 'terser', // 使用 terser 进行代码压缩
cssCodeSplit: true, // 启用 CSS 代码分割
chunkSizeWarningLimit: 500 // 设置 chunk 大小警告的限制(单位:kb)
}
})
配置说明:
-
target
: 指定生成代码的目标环境 -
minify
: 指定代码压缩方式 -
cssCodeSplit
: 控制 CSS 代码分割 -
chunkSizeWarningLimit
: 设置代码分块大小警告的阈值
这些配置主要用于优化生产环境的构建结果,提高应用性能。
11. Vite 的常见问题处理
1. 跨域配置
export default defineConfig({
server: {
proxy: {
'/api': { // 匹配所有 /api 开头的请求
target: 'http://example.com', // 代理目标地址
changeOrigin: true, // 修改请求头中的 Origin
rewrite: (path) => path.replace(/^\/api/, '') // 重写请求路径
// 例如:/api/users -> http://example.com/users
}
}
}
})
2. 路径别名配置
import path from 'path' // 需要先导入 path 模块
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, 'src') // 将 @ 解析为 src 目录的绝对路径
}
}
})
功能说明:
-
简化项目中的导入路径
-
@
符号指向 src 目录 -
使用
path.resolve
确保路径的正确性
// 使用别名导入
import Component from '@/components/Component.vue'
// 等同于
import Component from 'src/components/Component.vue'
12. Vite 的生产部署
1. 基本构建配置
export default defineConfig({
// 配置基础公共路径
base: '/app/', // 部署时的基础路径,如:https://example.com/app/
build: {
outDir: 'dist', // 指定构建输出目录
assetsDir: 'assets' // 指定静态资源存放目录,最终路径:dist/assets
}
})
功能说明:
-
base
: 设置部署时的基础路径 -
outDir
: 指定构建产物的输出目录 -
assetsDir
: 指定静态资源(如图片、CSS、JS)的存放目录
2. 多页面应用配置
import { resolve } from 'path' // 需要先导入 path 模块
export default defineConfig({
build: {
rollupOptions: {
input: {
// 配置多个入口页面
main: resolve(__dirname, 'index.html'), // 主页面
nested: resolve(__dirname, 'nested/index.html') // 嵌套页面
}
}
}
})
功能说明:
-
配置多页面应用的入口文件
-
main
: 指向主页面 HTML -
nested
: 指向其他页面 HTML -
使用
resolve
确保路径的正确解析
构建输出示例:
dist/
├── assets/
├── index.html
└── nested/
└── index.html
13. 重要概念解释
1. 依赖预构建
-
将
CommonJS/UMD
转换为 ESM -
将多个依赖合并
-
提高页面加载性能
-
按需加载
-
开发环境下基于
ESM
的按需加载
-
生产环境下基于
Rollup
的代码分割
-
HMR 原理
-
基于 ESM 的模块热替换
-
精确的更新范围
-
快速的更新速度
-
构建优化
-
Tree-shaking
-
代码分割
-
资源压缩