vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv, ConfigEnv, UserConfig } from 'vite'
import { getVitePlugins } from './build/plugins'
import { getBuildConfig } from './build/build'
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
// 加载环境变量
const env = loadEnv(mode, process.cwd())
// 当前执行 node 命令时文件夹的地址 工作目录
const root = process.cwd()
return {
root: root,
// 插件
plugins: getVitePlugins(mode),
// 别名配置
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
// 服务器配置
server: {
port: Number(env.VITE_API_BASE_PORT),
host: '0.0.0.0',
open: false,
proxy: env.VITE_USE_PROXY === 'true' ? {
[env.VITE_PROXY_URL]: {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(new RegExp(`^${env.VITE_APP_PROXY_URL}`), '')
}
} : undefined
},
// 构建配置
build: getBuildConfig(mode),
// 预构建优化大型依赖加载性能
optimizeDeps: {
// 强制预构建的依赖
include: ['lodash-es', 'axios', 'element-plus'],
// 排除的依赖
exclude: []
},
// CSS 预处理器配置
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "@/styles/variables.scss" as *;',
// 暂时禁用即将被废弃的 API 警告
silenceDeprecations: ["legacy-js-api"],
}
}
}
}
})
项目根目录下创建 build 文件夹 -> 用于配置打包、插件
build.ts
import { fileURLToPath, URL } from 'node:url'
import { loadEnv } from 'vite'
import type { PreRenderedAsset } from 'rollup'
export const getBuildConfig = (mode: string) => {
const env = loadEnv(mode, process.cwd())
return {
// 输出目录
outDir: 'dist',
// 静态资源目录
assetsDir: 'assets',
// 生成 sourcemap
sourcemap: false,
// 代码压缩方式
minify: 'esbuild' as const,
// 构建目标
target: 'es2015',
// 禁用压缩大小报告
reportCompressedSize: false,
// CSS代码分割
cssCodeSplit: true,
// 构建时清空输出目录
emptyOutDir: true,
// 构建时监听文件变化
watch: mode === 'development' ? {
include: ['src/**'],
exclude: ['node_modules/**', 'dist/**']
} : null,
// 资源内联大小限制 4kb
assetsInlineLimit: 4096,
// 配置打包压缩选项
esbuild: {
// 移除 console debugger
drop: env.VITE_DROP_CONSOLE_DEBUGGER === 'true' ? ['console', 'debugger'] : [],
// 移除注释
legalComments: 'none',
// 压缩配置
minifyIdentifiers: true,
minifySyntax: true,
minifyWhitespace: true,
// 目标环境
target: 'es2015',
},
// 块大小警告阈值 KB
chunkSizeWarningLimit: 2048,
// 环境变量处理
define: {
// 在代码中获取当前环境 console.log(__APP_ENV__)
__APP_ENV__: JSON.stringify(env.APP_ENV),
// 生产环境可以使用传统的 Options API 写法
__VUE_OPTIONS_API__: true,
// 在生产环境禁用 Vue DevTools
__VUE_PROD_DEVTOOLS__: false,
// 控制是否在生产环境显示水合 hydration 不匹配的详细信息
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
},
// CSS 处理配置
css: {
// CSS Modules 配置
modules: {
localsConvention: 'camelCase',
scopeBehavior: 'local',
generateScopedName: '[name]_[local]_[hash:base64:5]'
}
},
// 代码分割配置
rollupOptions: {
input: {
main: fileURLToPath(new URL('../index.html', import.meta.url))
},
output: {
// 单独打包
manualChunks: {
// UI库
'element-plus': ['element-plus'],
// 状态管理
'pinia': ['pinia'],
// 路由
'vue-router': ['vue-router'],
// 工具库
'utils': ['lodash-es', 'axios'],
// 核心框架
'vue': ['vue']
},
// 入口文件命名规则
entryFileNames: 'assets/js/[name].[hash].js',
// 代码分割后的文件命名规则
chunkFileNames: 'assets/js/[name].[hash].js',
// 打包目录结构优化 按照 img、js、css、other 进行分组
assetFileNames: (assetInfo: PreRenderedAsset) => {
if (!assetInfo.name) return 'assets/other/[name].[hash][extname]'
// 获取文件名和扩展名
const fileName = assetInfo.name
const ext = fileName.split('.').pop()?.toLowerCase()
// 根据文件类型分类
if (ext === 'svg' || ['png', 'jpg', 'jpeg', 'gif', 'webp', 'ico'].includes(ext || '')) {idea上方怎么添加当前代码处于哪个分支idea上方怎么添加当前代码处于哪个分支
return 'assets/img/[name].[hash][extname]'
} else if (['css', 'scss', 'sass', 'less'].includes(ext || '')) {
return 'assets/css/[name].[hash][extname]'
} else {
return 'assets/other/[name].[hash][extname]'
}
}
}
}
}
}
plugins.ts
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import { loadEnv } from 'vite'
export const getVitePlugins = (mode: string) => {
const env = loadEnv(mode, process.cwd())
return [
vue(),
vueJsx(),
env.VITE_USE_DEVTOOLS === 'true' && vueDevTools()
].filter(Boolean)
}
配合 .env
.env.development # 开发环境配置 VITE_APP_ENV=development # 开发环境标题 VITE_APP_TITLE=Web Project Base (Dev) # 开发环境服务接口 VITE_API_BASE_URL=http://192.168.2.127 # 开发环境端口 VITE_API_BASE_PORT=20000 # 开发环境超时配置 VITE_APP_API_TIMEOUT=15000 # 开发环境是否启用调试工具 VITE_USE_DEVTOOLS=true # 开发环境是否启用代理 VITE_USE_PROXY=true # 开发环境代理地址 VITE_PROXY_URL=/api # 开发环境是否删除 console.log debugger VITE_DROP_CONSOLE_DEBUGGER=false
.env.production # 生产环境配置 VITE_APP_ENV=production # 生产环境标题 VITE_APP_TITLE=Web Project Base # 生产环境服务接口 VITE_API_BASE_URL=http://192.168.2.127 # 生产环境端口 VITE_API_BASE_PORT=20000 # 生产环境超时配置 VITE_APP_API_TIMEOUT=15000 # 生产环境是否启用调试工具 VITE_USE_DEVTOOLS=false # 生产环境是否启用代理 VITE_USE_PROXY=false # 生产环境代理地址 VITE_PROXY_URL=/api # 生产环境是否删除 console.log debugger VITE_DROP_CONSOLE_DEBUGGER=true
.env.test # 测试环境配置 VITE_APP_ENV=test # 测试环境标题 VITE_APP_TITLE=Web Project Base (Test) # 测试环境服务接口 VITE_API_BASE_URL=http://192.168.2.127 # 测试环境端口 VITE_API_BASE_PORT=20000 # 测试环境超时配置 VITE_APP_API_TIMEOUT=15000 # 测试环境是否启用调试工具 VITE_USE_DEVTOOLS=false # 测试环境是否启用代理 VITE_USE_PROXY=false # 测试环境代理地址 VITE_PROXY_URL=/api # 测试环境是否删除 console.log debugger VITE_DROP_CONSOLE_DEBUGGER=true
打包结果展示:
