201 lines
5.5 KiB
JavaScript
201 lines
5.5 KiB
JavaScript
import { defineConfig, loadEnv } from "vite"
|
|
import removeConsole from "vite-plugin-remove-console" //生产环境移除console.log
|
|
import vue from "@vitejs/plugin-vue"
|
|
import { visualizer } from "rollup-plugin-visualizer"
|
|
import compression from "vite-plugin-compression"
|
|
import path from "path"
|
|
import cssnano from "cssnano" //压缩css工具
|
|
import imagemin from "unplugin-imagemin/vite" //图片压缩工具
|
|
|
|
export default defineConfig(({ mode, command }) => {
|
|
// 加载环境变量
|
|
const env = loadEnv(mode, process.cwd(), "")
|
|
const isProduction = command === "build"
|
|
const isAnalyze = mode === "analyze"
|
|
|
|
return {
|
|
plugins: [
|
|
vue(),
|
|
imagemin({
|
|
plugins: [
|
|
{
|
|
name: "imagemin-mozjpeg",
|
|
options: {
|
|
quality: 85
|
|
}
|
|
},
|
|
{
|
|
name: "imagemin-pngquant",
|
|
options: {
|
|
quality: [0.8, 0.9]
|
|
}
|
|
},
|
|
{
|
|
name: "imagemin-svgo",
|
|
options: {
|
|
plugins: [{ name: "removeViewBox" }, { name: "cleanupIDs", active: false }]
|
|
}
|
|
}
|
|
]
|
|
}),
|
|
// 生产环境才移除console
|
|
isProduction && removeConsole(),
|
|
// 生产环境开启gzip 压缩
|
|
isProduction &&
|
|
compression({
|
|
algorithm: "gzip",
|
|
ext: ".gz",
|
|
threshold: 10240 // 10KB以上才压缩
|
|
}),
|
|
// 构建分析
|
|
isAnalyze &&
|
|
visualizer({
|
|
query: "?url",
|
|
import: "default",
|
|
filename: "dist/stats.html",
|
|
open: true,
|
|
gzipSize: true
|
|
})
|
|
].filter(Boolean),
|
|
|
|
assetsInclude: ["**/*.csv"],
|
|
|
|
css: {
|
|
preprocessorOptions: {
|
|
scss: {
|
|
//全局导入自适应px转换vw vh sass函数
|
|
additionalData: `
|
|
@use "@/utils/px-to-vw-vh.scss" as *;
|
|
`
|
|
}
|
|
},
|
|
|
|
// 生产环境压缩 CSS
|
|
...(isProduction && {
|
|
postcss: {
|
|
plugins: [
|
|
cssnano({
|
|
preset: "default"
|
|
})
|
|
]
|
|
}
|
|
})
|
|
},
|
|
|
|
resolve: {
|
|
alias: {
|
|
"@": path.resolve(__dirname, "src"),
|
|
"@assets": path.resolve(__dirname, "src/assets"),
|
|
"@components": path.resolve(__dirname, "src/components"),
|
|
"@views": path.resolve(__dirname, "src/views"),
|
|
"@utils": path.resolve(__dirname, "src/utils")
|
|
}
|
|
},
|
|
|
|
server: {
|
|
open: true,
|
|
proxy: {
|
|
"/api": {
|
|
target: "http://172.16.20.3:5080",
|
|
changeOrigin: true
|
|
// rewrite: (path) => path.replace(/^\/api/, "")
|
|
}
|
|
},
|
|
// 开发服务器优化
|
|
cors: true,
|
|
hmr: {
|
|
overlay: true
|
|
}
|
|
},
|
|
|
|
build: {
|
|
target: "es2018", // JavaScript 代码,转换成兼容 ES2018 标准的代码
|
|
chunkSizeWarningLimit: 1000, // 减少警告
|
|
reportCompressedSize: false,
|
|
assetsInlineLimit: 4096, // 资源内联限制优化
|
|
rollupOptions: {
|
|
output: {
|
|
// 手动代码分割优化
|
|
manualChunks: (id) => {
|
|
if (id.includes("node_modules")) {
|
|
// 将大的第三方库单独分包
|
|
if (id.includes("echarts") || id.includes("zrender")) return "vendor-echarts"
|
|
if (id.includes("element-plus")) return "vendor-element"
|
|
if (id.includes("vue")) return "vendor-vue"
|
|
if (id.includes("lodash") || id.includes("underscore")) return "vendor-lodash"
|
|
return "vendor"
|
|
}
|
|
// 路由级别代码分割
|
|
if (id.includes("/views/") || id.includes("/pages/")) {
|
|
const match = id.match(/(?:views|pages)\/([^/]+)/)
|
|
if (match && match[1]) {
|
|
return `view-${match[1]}`
|
|
}
|
|
}
|
|
},
|
|
// 环境差异化命名
|
|
chunkFileNames: isProduction ? "js/[name]-[hash:8].js" : "js/[name].js",
|
|
entryFileNames: isProduction ? "js/[name]-[hash:8].js" : "js/[name].js",
|
|
// 优化的资源文件处理
|
|
assetFileNames: (assetInfo) => {
|
|
if (!assetInfo.names || assetInfo.names.length === 0)
|
|
return "assets/[name]-[hash][extname]"
|
|
const ext = assetInfo.names[0].split(".").pop().toLowerCase()
|
|
const hash = isProduction ? "-[hash:8]" : ""
|
|
// 精细化文件分类
|
|
const assetMap = {
|
|
// 图片
|
|
png: "img",
|
|
jpeg: "img",
|
|
jpg: "img",
|
|
gif: "img",
|
|
svg: "img",
|
|
webp: "img",
|
|
avif: "img",
|
|
ico: "img",
|
|
|
|
// 样式
|
|
css: "css",
|
|
less: "css",
|
|
scss: "css",
|
|
sass: "css",
|
|
|
|
// 字体
|
|
woff: "fonts",
|
|
woff2: "fonts",
|
|
eot: "fonts",
|
|
ttf: "fonts",
|
|
otf: "fonts",
|
|
|
|
// 媒体
|
|
mp4: "media",
|
|
webm: "media",
|
|
ogg: "media",
|
|
mp3: "media",
|
|
wav: "media",
|
|
|
|
// 数据
|
|
json: "data",
|
|
xml: "data",
|
|
csv: "data"
|
|
}
|
|
const dir = assetMap[ext] || "assets"
|
|
return `${dir}/[name]${hash}[extname]`
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// 预览服务器配置
|
|
preview: {
|
|
port: 4173,
|
|
open: true,
|
|
cors: true
|
|
},
|
|
// ESBuild 优化
|
|
esbuild: {
|
|
drop: isProduction ? ["console", "debugger"] : []
|
|
}
|
|
}
|
|
})
|