const path = require('path')
// 使用compression-webpack-plugin插件压缩打包的静态资源,优化项目性能
const CompressionPlugin = require('compression-webpack-plugin') // 需 npm install compression-webpack-plugin --save-dev
const TerserPlugin = require('terser-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 需 npm install clean-webpack-plugin --save-dev
// 后端nginx配置
/*
主要是下方的gizp配置哦
gzip on; # 开启gzip压缩
gzip_min_length 10k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启
*/
const port = process.env.port || process.env.npm_config_port || 80 // 端口
module.exports = {
// # 管理系统/开发环境 VUE_APP_BASE_API = '/dev-api'
// 部署生产环境和开发环境下的URL。
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ibp.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ibp.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath:
process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/',
/* 当运行 npm run build 时生成的生产环境构建文件的目录。注意目标目录在构建之前会被清除 (构建时传入 --no-clean 可关闭该行为)。 */
outputDir: 'dist',
// 静态资源目录(相对于 outputDir)
assetsDir: 'static',
// 文件名哈希(用于缓存控制)
filenameHashing: true,
lintOnSave: true /* 保存时是否执行 eslint-loader 的语法检查 */,
productionSourceMap: false /* 默认值是true,如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建 */,
css: {
/* css相关配置 */
extract: true /* 默认值:生产环境下是 true,开发环境下是 false。是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。*/,
sourceMap: false /* 默认值:false。是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能 */,
loaderOptions: {} /* 向 CSS 相关的 loader 传递选项 */
},
// 禁用现代模式(Vue2 对 modern mode 支持有限,可能增加构建时间)
modern: false,
devServer: {
/* 针对开发的配置 */
open: true /* 项目启动起来后自动在浏览器中打开首页。默认值:false string。true-使用默认浏览器;也可使用string类型配置浏览器名称,如 Google Chrome */,
host: '0.0.0.0' /* 主机配置,默认情况下是本机 localhost , 0.0.0.0 即本机*/,
port: port /* 端口 */,
https: false /* 默认通过HTTP提供服务。当为true时通过HTTPS提供服务 */,
proxy: {
/* 设置代理服务器(前端应用和后端 API 服务器没有运行在同一个主机上时需要配置此项) */
[process.env.VUE_APP_BASE_API]: {
target: 'http://1.1.1.1:8080' /* 后端服务器ip */,
changeOrigin: true /* 是否跨域,此项解决跨域问题 */,
// 可选:支持WebSocket
ws: true,
pathRewrite: {
/* 路径重写 */
['^' + process.env.VUE_APP_BASE_API]:
'' /* 移除url中多于的 /api,当然,也可以配置成其它路径 */
}
}
}
},
configureWebpack: (config) => {
// 生产环境优化
if (process.env.NODE_ENV === 'production') {
// 清除dist目录
config.plugins.push(new CleanWebpackPlugin())
// 压缩成gzip
config.plugins.push(
new CompressionPlugin({
test: /\.(js|css|html|svg)$/,
threshold: 8192, // 大于8kb的文件才压缩
minRatio: 0.8,
algorithm: 'gzip'
})
)
// 代码压缩与优化
config.optimization = {
minimizer: [
new TerserPlugin({
parallel: true, // 多进程压缩
terserOptions: {
compress: {
drop_console: true, // 移除console
drop_debugger: true // 移除debugger
}
}
})
],
// 分割代码块
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: 5,
chunks: 'initial',
reuseExistingChunk: true
}
}
}
}
} else {
// 开发环境配置
config.devtool = 'source-map' // 开发环境开启sourceMap
}
},
chainWebpack: (config) => {
config.optimization.minimize(true)
config.optimization.splitChunks({
chunks: 'all'
})
// 图片压缩
// config.module
// .rule('images')
// .use('image-webpack-loader')
// .loader('image-webpack-loader')
// .options({
// bypassOnDebug: true
// })
// .end()
config.resolve.alias
.set('@', path.resolve(__dirname, 'src'))
.set('assets', path.resolve(__dirname, 'src/assets'))
.set('components', path.resolve(__dirname, 'src/components'))
// 移除 prefetch 插件(预加载未使用的异步 chunk,浪费带宽)
config.plugins.delete('prefetch-index')
// 移除 preload 插件(根据实际需求决定是否保留)
config.plugins.delete('preload-index')
// 配置图片处理
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 4096, // 小于4kb的图片转为base64
fallback: {
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]' // 图片输出路径
}
}
})
// 图片优化:小图片转 base64,大图片压缩
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 4096, // 4kb 以下转 base64(减少请求)
fallback: {
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]' // 带哈希值防缓存
}
}
})
.end()
.use('image-webpack-loader') // 压缩图片
.loader('image-webpack-loader') // 需安装:npm install image-webpack-loader --save-dev
.options({
mozjpeg: { quality: 80 }, // jpeg 压缩
optipng: { enabled: false } // 禁用 png 压缩(可选)
})
.end()
// 生产环境压缩 CSS
if (process.env.NODE_ENV === 'production') {
config
.plugin('optimize-css')
.use(require('optimize-css-assets-webpack-plugin'))
}
}
}