📖 核心概念
- Vite核心原理:原生ESM+HMR
- Vite配置详解
- 插件系统与常用插件
- 环境变量与模式
- 构建优化:分包、压缩、CDN
- Vite vs Webpack对比
💻 代码实现
Vite配置实战
✅ javascript
// vite.config.ts
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
import { visualizer } from 'rollup-plugin-visualizer';
import { compression } from 'vite-plugin-compression';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd());
return {
plugins: [
react(),
svgr(),
compression({ algorithm: 'gzip' }),
mode === 'analyze' && visualizer({ open: true }),
].filter(Boolean),
resolve: {
alias: {
'@': '/src',
'@components': '/src/components',
'@hooks': '/src/hooks',
'@stores': '/src/stores',
'@utils': '/src/utils',
},
},
css: {
modules: {
localsConvention: 'camelCase',
},
preprocessorOptions: {
scss: {
additionalData: \`@import "@/styles/variables";\`,
},
},
},
server: {
port: 3000,
open: true,
proxy: {
'/api': {
target: env.VITE_API_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
build: {
target: 'es2020',
outDir: 'dist',
sourcemap: mode === 'development',
minify: 'terser',
terserOptions: {
compress: { drop_console: mode === 'production' },
},
rollupOptions: {
output: {
manualChunks: (id) => {
if (id.includes('node_modules')) {
if (id.includes('react')) return 'react-vendor';
if (id.includes('lodash')) return 'lodash-vendor';
return 'vendor';
}
},
chunkFileNames: 'js/[name]-[hash].js',
assetFileNames: (info) => {
const ext = info.name.split('.').pop();
const map = { css: 'css', svg: 'images', png: 'images' };
return \`\${map[ext] || 'assets'}/[name]-[hash].[ext]\`;
},
},
},
},
optimizeDeps: {
include: ['react', 'react-dom', 'react-router-dom'],
},
};
});
自定义Vite插件
✅ javascript
// 自定义Vite插件:自动生成路由
function autoRoutesPlugin(options = {}) {
const { dir = 'src/pages', prefix = '' } = options;
const virtualModuleId = 'virtual:auto-routes';
const resolvedId = '\0' + virtualModuleId;
return {
name: 'vite-plugin-auto-routes',
resolveId(id) {
if (id === virtualModuleId) return resolvedId;
},
async load(id) {
if (id !== resolvedId) return;
// 扫描pages目录生成路由
const pages = await globby(dir);
const routes = pages
.filter(f => f.endsWith('.tsx'))
.map(file => {
const path = file
.replace(dir, '')
.replace('/index.tsx', '')
.replace('.tsx', '')
.replace(/\[([^\]]+)\]/g, ':$1')
|| '/';
return { path: prefix + path, component: file };
});
return \`export const routes = \${JSON.stringify(routes, null, 2)}\`;
},
};
}
// 环境变量类型安全
// src/env.d.ts
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_APP_TITLE: string;
readonly VITE_ENABLE_ANALYTICS: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
// .env.development
// VITE_API_URL=http://localhost:3001
// VITE_APP_TITLE=开发环境
// .env.production
// VITE_API_URL=https://api.example.com
// VITE_APP_TITLE=生产环境
🔍 Vite开发技巧
Vite的开发服务器基于原生ESM,首次启动极快。但首次访问页面时需要预编译依赖,可能稍慢。使用optimizeDeps.include预声明常用依赖可以加速。生产构建使用Rollup,支持Tree Shaking和代码分割。常见问题:CJS依赖需要预编译、Glob导入动态路径、SSR兼容性。
🎯 练习任务
- 1 创建一个完整的Vite项目配置,包含代理、环境变量、分包策略
- 2 编写一个自定义Vite插件,实现自动导入组件
- 3 对比Vite开发模式和生产构建的模块处理差异
- 4 配置Vite的CDN外部化,减小打包体积
🏆 成就解锁
构建配置师 — 掌握Vite配置与插件开发,打造极速开发体验