官网解释:
https://vitejs.cn/vite3-cn/config/build-options.html#build-minify
build.minify
类型: boolean | 'terser' | 'esbuild'
默认: 'esbuild'
设置为 false 可以禁用最小化混淆,或是用来指定使用哪种混淆器。默认为 Esbuild,它比 terser 快 20-40 倍,压缩率只差 1%-2%。
注意,在 lib 模式下使用 'es' 时,build.minify 选项不会缩减空格,因为会移除掉 pure 标注,导致破坏 tree-shaking。
当设置为 'terser' 时必须先安装 Terser。
npm add -D terser
遇到的问题:
javascript
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { libInjectCss } from 'vite-plugin-lib-inject-css'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
const isProduction = mode === 'production'
return {
plugins: [
vue(),
libInjectCss()
],
build: {
lib: {
entry: resolve(__dirname, 'packages/index.js'),
name: 'TalosExplainPlayer',
formats: ['es', 'umd'],
fileName: (format) => `talos-explain-player.${format}.js`
},
rollupOptions: {
external: ['vue', 'element-plus'],
output: {
globals: {
vue: 'Vue',
'element-plus': 'ElementPlus'
}
}
},
// 使用 terser 进行代码压缩(生产环境)
minify: isProduction ? 'terser' : false,
terserOptions: isProduction ? {
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.info', 'console.debug']
},
mangle: {
safari10: true
},
format: {
comments: false
}
} : {}
},
server: {
port: 5173,
host: true
},
define: {
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
// 将环境变量注入到 import.meta.env 中
'import.meta.env.VITE_APP_BASE_URL': JSON.stringify(env.VITE_APP_BASE_URL),
'import.meta.env.NODE_ENV': JSON.stringify(env.NODE_ENV)
}
}
})
最终解决:
使用 @rollup/plugin-terser 作为 Rollup 插件;优势:作为 Rollup 插件,会处理所有输出格式(包括 ES 和 UMD)
javascript
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { libInjectCss } from 'vite-plugin-lib-inject-css'
import terser from '@rollup/plugin-terser'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
const isProduction = mode === 'production'
return {
plugins: [
vue(),
libInjectCss()
],
build: {
lib: {
entry: resolve(__dirname, 'packages/index.js'),
name: 'TalosExplainPlayer',
formats: ['es', 'umd'],
fileName: (format) => `talos-explain-player.${format}.js`
},
rollupOptions: {
external: ['vue', 'element-plus'],
output: {
globals: {
vue: 'Vue',
'element-plus': 'ElementPlus'
}
},
// 生产环境下使用 terser 压缩所有格式(包括 ES 格式)
plugins: isProduction ? [
terser({
ecma: 2020,
module: true,
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.info', 'console.debug']
},
mangle: {
safari10: true
},
format: {
comments: false
}
})
] : []
}
},
server: {
port: 5173,
host: true
},
define: {
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
// 将环境变量注入到 import.meta.env 中
'import.meta.env.VITE_APP_BASE_URL': JSON.stringify(env.VITE_APP_BASE_URL),
'import.meta.env.NODE_ENV': JSON.stringify(env.NODE_ENV)
}
}
})
原因:
为什么应用模式可以生效?为什么库模式不生效?
在应用模式下:
● Vite 会压缩所有输出文件
● 不需要考虑 tree-shaking 的 pure 标注
● 输出是最终应用,不是供他人使用的库
● build.minify 对所有格式都生效
在库模式下:
● Vite 需要保留 /#PURE/ 等注释以支持 tree-shaking
● ES 模块通常由最终用户的应用构建工具处理
● 因此 Vite 在库模式下对 ES 格式不压缩(或只做有限压缩)
● 文档说明:不会缩减空格,实际可能完全不压缩
总结:
| 特性 | 应用模式 (build.lib) |
库模式 (build.lib) |
|---|---|---|
| 存在性 | ❌ 无 | ✅ 有 |
build.minify 对 ES 格式 |
✅ 生效 | ❌ 不生效 |
| 输出用途 | 最终应用 | 供他人使用的库 |
| 压缩策略 | 完全压缩 | 保留 tree-shaking 标记 |