// 对依赖进行转换
transpileDependencies: true,
// 生产关闭sourceMap
productionSourceMap: false,
outputDir: 'bundle', // 打包后文件的目录 (默认为dist)
assetsDir: 'static', // outputDir的静态资源(js、css、img、fonts)目录 默认为‘’没有单独目录js/css/img在根目录中。
// 修改浏览器的icon图标,不加下面的,修改浏览器图标不生效
pwa: {
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico',
}
}
chainWebpack: config => {
config.optimization.minimizer('terser').tap(args => {
// 删除代码中的注释和打印,减少一点代码体积
args.forEach(item => {
if (item.hasOwnProperty('terserOptions')) {
Object.assign(item['terserOptions'].compress, {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
})
}
item['terserOptions']['format'] = {
comments: false
}
})
return args
})
// 开启 gzip 压缩
if (process.env.NODE_ENV === "production") {
config.plugin('CompressionPlugin').use(
new CompressionWebpackPlugin({
test: /\.(js|css|less|scss|html)$/, // 将 css、scss、less、html 进行压缩
threshold: 10240, // 超过10kb的文件就压缩
deleteOriginalAssets: false, // 不删除源文件
minRatio: 0.8, // 最小压缩率 0.8
algorithm: 'gzip'
})
)
}
}
configureWebpack: {
// 代码分割
optimization: {
splitChunks: {
chunks: "all",
// 定义一个cache组,将第三方的包抽离出来
cacheGroups: {
elementUI: {
// 抽离出来的名字
name: "element-chunk-vendors",
// 在node_modules包里面找
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
// 权重,越大优先打包
priority: 30,
},
vue: {
name: "vue-chunk-vendors",
test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
chunks: "initial",
priority: 20,
reuseExistingChunk: true,
},
vueRouter: {
name: "vueRouter-chunk-vendors",
test: /[\\/]node_modules[\\/]vue-router(.*)[\\/]/,
chunks: "initial",
priority: 19,
},
vuex: {
name: "vuex-chunk-vendors",
test: /[\\/]node_modules[\\/]vuex(.*)[\\/]/,
chunks: "initial",
priority: 18,
},
echarts: {
name: "echarts-chunk-vendors",
test: /[\\/]node_modules[\\/]echarts(.*)[\\/]/,
chunks: "initial",
priority: 17,
},
// 剩下的别忘记单独抽离
libs: {
name: "chunk-libs-vendors",
test: /[\\/]node_modules[\\/]/,
priority: 1, // 权重最低,优先考虑前面内容
chunks: "initial",
},
// 针对自己写的代码,重复使用的满足下面的配置就会抽离出来单独打包,比如 utils 下面的包
default: {
// 其他没有写的配置会使用上面的默认值
test: /[\\/]src(.*)[\\/]/,
name: "common-chunk",
minSize: 20000, // 超过 20kb,就会拆包
minChunks: 2, // 引用两次就会拆包
priority: -10,
reuseExistingChunk: true
}
}
}
},
// 配置别名
resolve: {
alias: {
"#": path.resolve(__dirname, "src")
}
},
// 分析插件
plugins: [
new BundleAnalyzer({
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8088,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'state.json',
statsOptions: null,
logLevel: 'info'
})
]
}
const path = require("path")
const { defineConfig } = require('@vue/cli-service')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = defineConfig({
// 对依赖进行转换
transpileDependencies: true,
// 生产关闭sourceMap
productionSourceMap: false,
outputDir: 'bundle', // 打包后文件的目录 (默认为dist)
assetsDir: 'static', // outputDir的静态资源(js、css、img、fonts)目录 默认为‘’没有单独目录js/css/img在根目录中。
// 修改浏览器的icon图标
pwa: {
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico',
}
},
// webpack 配置(写在此处的配置可以覆盖掉脚手架本来就预设上有的配置)
chainWebpack: config => {
config.optimization.minimizer('terser').tap(args => {
// 删除代码中的注释和打印,减少一点代码体积
args.forEach(item => {
if (item.hasOwnProperty('terserOptions')) {
Object.assign(item['terserOptions'].compress, {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
})
}
item['terserOptions']['format'] = {
comments: false
}
})
return args
})
// 开启 gzip 压缩,对应的 nginx 也需要配置
if (process.env.NODE_ENV === "production") {
config.plugin('CompressionPlugin').use(
new CompressionWebpackPlugin({
test: /\.(js|css|less|scss|html)$/, // 将 css、scss、less、html 进行压缩
threshold: 10240, // 超过10kb的文件就压缩
deleteOriginalAssets: false, // 不删除源文件
minRatio: 0.8, // 最小压缩率 0.8
algorithm: 'gzip'
})
)
}
},
// webpack 配置(写在此处的都是预设没有配置的,脚手架本来就有的配置是不会覆盖的)
configureWebpack: {
// 代码分割
optimization: {
splitChunks: {
chunks: "all",
// 定义一个cache组,将第三方的包抽离出来
cacheGroups: {
elementUI: {
// 抽离出来的名字
name: "element-chunk-vendors",
// 在node_modules包里面找
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
// 权重,越大优先打包
priority: 30,
},
vue: {
name: "vue-chunk-vendors",
test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
chunks: "initial",
priority: 20,
reuseExistingChunk: true,
},
vueRouter: {
name: "vueRouter-chunk-vendors",
test: /[\\/]node_modules[\\/]vue-router(.*)[\\/]/,
chunks: "initial",
priority: 19,
},
vuex: {
name: "vuex-chunk-vendors",
test: /[\\/]node_modules[\\/]vuex(.*)[\\/]/,
chunks: "initial",
priority: 18,
},
echarts: {
name: "echarts-chunk-vendors",
test: /[\\/]node_modules[\\/]echarts(.*)[\\/]/,
chunks: "initial",
priority: 17,
},
// 剩下的别忘记单独抽离
libs: {
name: "chunk-libs-vendors",
test: /[\\/]node_modules[\\/]/,
priority: 1, // 权重最低,优先考虑前面内容
chunks: "initial",
},
// 针对自己写的代码,重复使用的满足下面的配置就会抽离出来单独打包,比如 utils 下面的包
default: {
// 其他没有写的配置会使用上面的默认值
test: /[\\/]src(.*)[\\/]/,
name: "common-chunk",
minSize: 20000, // 超过 20kb,就会拆包
minChunks: 2, // 引用两次就会拆包
priority: -10,
reuseExistingChunk: true
}
}
}
},
// 配置别名
resolve: {
alias: {
"#": path.resolve(__dirname, "src")
}
},
plugins: [
new BundleAnalyzer({
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8088,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'state.json',
statsOptions: null,
logLevel: 'info'
})
]
}
})
// 打包分析工具加了之后 启动需要加上:
"build": "vue-cli-service build",
"build:analyze": "cross-env NODE_ENV=production npm_config_report=true vue-cli-service build"
https://juejin.cn/post/6951297954770583565
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import viteCompression from "vite-plugin-compression";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({//自定义的模块
dirs: ['src/components'],
extensions: ['vue', 'ts'],
resolvers: [ElementPlusResolver()]
}),
AutoImport({ // 插件进行自动导入相关的依赖库
//安装两行后你会发现在组件中不用再导入ref,reactive等
imports: ['vue', 'vue-router'],
// 可选,用于自动导入组件类型
dts: 'src/components.d.ts'
}),
// 开启gzip压缩
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz',
})
],
// 打包
build: {
// 打包删除 console 和 debugger
minify: "terser",
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: { //静态资源分类打包
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
manualChunks(id: string) {
// node_modules 拆包
if (id.indexOf('node_modules') !== -1) {
if (id.indexOf('vue') !== -1) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
if (id.indexOf('vue-router') !== -1) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
if (id.indexOf('pinia') !== -1) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
if (id.indexOf('element-plus') !== -1) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
}
});