修改vue.config.js
//vue.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const path = require('path');
const isProduction = process.env.NODE_ENV !== 'development';
const port = process.env.port || process.env.npm_config_port || 8998; // 端口
const themePath = process.env.VUE_APP_THEME ? `-${ process.env.VUE_APP_THEME }` : '';
module.exports = {
publicPath: process.env.PATH_SUFFIX,
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: true,
devServer: {
port: port,
open: true,
proxy: {
'/api': {
target: process.env.VUE_APP_URL,
changeOrgin: true,
pathRewrite: {
'^/api': ''
}
},
'/dapi': {
target: process.env.VUE_APP_URL,
changeOrgin: true,
pathRewrite: {
'^/dapi': ''
}
},
},
},
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [ path.resolve(__dirname, `src/assets/less/index${ themePath }.less`) ] // 引入全局样式变量
}
},
css: {
extract: true,
sourceMap: false,
requireModuleExtension: true
},
configureWebpack: {
externals: {
'AMap': 'AMap', // 高德地图配置
'AMapUI': 'AMapUI', // 高德地图AMapUI
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
performance: {
'maxEntrypointSize': 10000000,
'maxAssetSize': 30000000,
// 只给出 js 文件的性能提示
assetFilter: function (assetFilename) {
return assetFilename.endsWith('.js')
}
},
optimization: {
minimizer: [
new UglifyJsPlugin({ // 代码压缩
uglifyOptions: {
output: {
comments: false, // 删除注释
beautify: false, // 最紧凑的输出
},
compress: {
drop_debugger: true, //清除 debugger 语句
drop_console: true, //清除console语句
pure_funcs: [ 'console.log' ],
collapse_vars: true,
reduce_vars: true
}
},
sourceMap: false,
parallel: true, // 并行处理打包文件
cache: true
})
],
splitChunks: {
chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
// maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
// minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
// maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'all',
enforce: true
},
element: {
chunks: 'all',
name: 'element-ui',
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
priority: 0,
enforce: true
},
xlsx: {
name: 'chunk-xlsxjs',
test: /[\\/]node_modules[\\/]_?xlsx(.*)/,
priority: 1,
enforce: true
},
pdf: {
name: 'chunk-pdfjs',
test: /[\\/]node_modules[\\/]_?pdf+(.*)/,
priority: 1,
enforce: true
},
bpmn: {
name: 'chunk-bpmnjs',
test: /[\\/]node_modules[\\/]_?bpmn(.*)/,
priority: 1,
enforce: true
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'chunk-commons',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
reuseExistingChunk: true
},
components: {
chunks: 'all',
test: /[\\/]src[\\/]components[\\/]/,
priority: 2,
name: 'chunk-components',
},
mixin: {
chunks: 'all',
test: /[\\/]src[\\/]mixin[\\/]/,
priority: 2,
name: 'chunk-mixin',
},
mapjson: {
chunks: 'all',
test: /[\\/]src[\\/]views[\\/]map[\\/]map_data(.json)/,
priority: 2,
name: 'chunk-mapjson',
enforce: true
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
}
}
}
},
chainWebpack: config => {
if (isProduction) { // 生产环境相关配置
const productionGzipExtensions = [ 'html', 'js', 'css' ]
config.plugin('compressionPlugin')
.use(new CompressionPlugin({
filename: '[path].gz[query]', // 压缩后的文件名
algorithm: 'gzip', // 使用gzip压缩
test: new RegExp(
`\\.(${ productionGzipExtensions.join('|') })$`
),
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除未压缩的文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false
}));
}
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
mozjpeg: { progressive: true, quality: 50 }, // 压缩JPEG图像
optipng: { enabled: true }, // 压缩PNG图像
// pngquant: { quality: [ 0.5, 0.65 ], speed: 4 }, // 压缩PNG图像
gifsicle: { interlaced: false }, // 压缩GIF图像
bypassOnDebug: true
})
.end();
// 移除 prefetch 插件
config.plugins.delete('prefetch')
// 移除 preload 插件
config.plugins.delete('preload');
}
}