说明:vue inspect 查看当前项目默认的webpack配置信息 (重要)
插件地址:www.webpackjs.com/plugins/
一、compression-webpack-plugin 开启Gzip压缩
1、compression-webpack-plugin作用
作用:提升网络传输速率=>优化web页面加载时间
可以借助CompressionWebpackPlugin插件来提前对文件进行Gzip压缩。
这样服务器查找到有与源文件同名的.gz文件就会直接读取,不会主动压缩,降低cpu负载,优化了服务器性能。
*基本原理
1)浏览器请求资源文件时会自动带一个Accept-Encoding的请求头告诉服务器支持的压缩编码类型;
2)服务器配置开启gzip选项:
接收客户端资源文件请求,查看请求头Content-encoding支持的压缩编码格式,如果是包含gzip那么在每次响应资源请求之前进行gzip编码压缩后再响应返回资源文件(在响应头会带上Content-encoding: gzip)。
3)浏览器接收到响应后查看请求头是否带有Content-encoding:gzip,如果有进行对返回的资源文件进行解压缩然后再进行解析渲染。
2、compression-webpack-plugin 项目使用
1、安装 compression-webpack-plugin
npm install compression-webpack-plugin --save-dev
复制代码
*npm地址:www.npmjs.com/package/com…
2、Vue-cli3 的 vue.config.js 配置
const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
// 设置一些webpack配置项,用这些配置项和默认的配置项合并
configureWebpack: {
plugins: [
new CompressionWebpackPlugin({
// 发现这货2.x版本将1.x版本的配置项asset更换成了filename
filename: info => `${info.path}.gz${info.query}`, // 打包后,在dist文件中有.gz文件
algorithm: 'gzip', // 开启gzip
threshold: 10240, // 对超过10.24k的数据压缩
test: new RegExp(`\\.(${['js'].join('|')})$`), // 匹配文件名
// test: new RegExp('.(' + ['js', 'css'].join('|') + ')$'),
minRatio: 0.8, // 压缩比
deleteOriginalAssets: false, // 不删除源文件
})
]
}
}
复制代码
二、image-webpack-loader图片压缩使用
1、image-webpack-loader 作用
webpack 中使用图片压缩 (PNG, JPEG, GIF, SVG和WEBP) 能极大的减少包的大小,对于前端来说也是一个重要的优化点。
这里就推荐使用 image-webpack-loader,还有像 img-loader 和 imagemin-webpack-plugin 等其实底层调用的借口都是类似的。
2、image-webpack-loader 项目使用
**1、**安装 image-webpack-loader
npm install image-webpack-loader --save-dev
复制代码
*npm地址:www.npmjs.com/package/ima…
**2、**Vue-cli3 的 vue.config.js 配置
module.exports = {
// 直接去修改内置的webpack配置项
chainWebpack: (config) => {
// 图片压缩
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true,
})
.end();
}
}
复制代码
2、遇到的问题
webpack图片压缩image-webpack-loader无法安装或安装卡死,安装完后,再install的时候直接卡死,半天不动。
*总结问题:包安装的问题,npm下载下来的时候因为翻墙的问题,包下载的不完全 (问题必现)
3、解决方法
操作步骤方法1:(win操作)
1、若安装过 image-webpack-loader 先卸载
npm uninstall image-webpack-loader
复制代码
2、使用 cnpm , 这一步意思就是安装 cnpm 然后将全局的 registry 设置成阿里的镜像,国内阿里比较快
npm install cnpm -g --registry=https://registry.npm.taobao.org
复制代码
3、使用 cnpm 安装 image-webpack-loader 会发现很快就安装好了
cnpm install --save-dev image-webpack-loader
复制代码
操作步骤方法2:(Mac操作)
1、暂时去掉:package.json。例如:”image-webpack-loader”: “^7.0.1”
2、vue.config.js 注释代码
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true,
})
.end();
复制代码
3、包安装成功后,cnpm 安装 image-webpack-loader,然后vue.config.js 恢复
sudo cnpm install image-webpack-loader --save-dev
复制代码
三、uglifyjs-webpack-plugin 代码压缩,删除console与注释
1、uglifyjs-webpack-plugin作用
uglifyJsPlugin 用来对js文件进行压缩,减小js文件的大小。其会拖慢webpack的编译速度,建议开发环境时关闭,生产环境再将其打开。
2、uglifyjs-webpack-plugin 项目使用
1、安装uglifyjs-webpack-plugin
npm install uglifyjs-webpack-plugin --save-dev
复制代码
*npm地址:www.npmjs.com/package/ugl…
2、Vue-cli3 的 vue.config.js 配置
const UglifyPlugin = require('uglifyjs-webpack-plugin');
optimization: {
minimizer: [
new UglifyPlugin({
uglifyOptions: {
// 删除注释
output:{
comments:false
},
// 删除console debugger 删除警告
compress: {
warnings: false,
drop_console: true,//console
drop_debugger: false,
pure_funcs: ['console.log']//移除console
}
}
})
]
}
复制代码
四、配置代理转发devServer.proxy
1、devServer.proxy作用
跨域处理的方式。跨域指协议、域名、端口三者之间任意一个与当前页面url不同。
2、devServer.proxy 项目使用
devServer: { //匹配规则
open: false, // 自动启动浏览器
host: '0.0.0.0', // localhost
port: 6060, // 端口号
https: false,
hotOnly: false, // 热更新
proxy: {
'/api': {
target: "https://www.baidu.cn/", //跨域网址
ws: true, //开启WebSocket
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, // //自动修改http header里面的host
pathRewrite: {
"^/api": "", //路径的替换规则
}
}
}
}
复制代码
**说明:**pathRewrite:如果不写则只能修改代理的域名,如果写则可以修改代理的域名和后边的路径。
五、只打包改变的文件
安装 npm i webpack -D
const { HashedModuleIdsPlugin } = require('webpack');
configureWebpack: config => {
const plugins = [];
plugins.push(
new HashedModuleIdsPlugin()
)
}
复制代码
六、开启分析打包日志
安装 npm i webpack-bundle-analyzer -D
chainWebpack: config => {
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
}
复制代码
七、vue.config.js 完整的架构配置(参考)
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 去掉注释
const CompressionWebpackPlugin = require('compression-webpack-plugin'); // 开启压缩
const { HashedModuleIdsPlugin } = require('webpack');
function resolve(dir) {
return path.join(__dirname, dir)
}
const isProduction = process.env.NODE_ENV === 'production';
// cdn预加载使用
const externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
"element-ui": "ELEMENT"
}
const cdn = {
// 开发环境
dev: {
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
],
js: []
},
// 生产环境
build: {
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
],
js: [
'https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vue-router@3.0.1/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/vuex@3.0.1/dist/vuex.min.js',
'https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js',
'https://unpkg.com/element-ui/lib/index.js'
]
}
}
module.exports = {
lintOnSave: false, // 关闭eslint
productionSourceMap: false,
publicPath: './',
outputDir: process.env.outputDir, // 生成文件的目录名称
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('src'))
// 压缩图片
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
// webpack 会默认给commonChunk打进chunk-vendors,所以需要对webpack的配置进行delete
config.optimization.delete('splitChunks')
config.plugin('html').tap(args => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = cdn.build
}
if (process.env.NODE_ENV === 'development') {
args[0].cdn = cdn.dev
}
return args
})
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
},
configureWebpack: config => {
const plugins = [];
if (isProduction) {
plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
output: {
comments: false, // 去掉注释
},
warnings: false,
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log']//移除console
}
}
})
)
// 服务器也要相应开启gzip
plugins.push(
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /\.(js|css)$/,// 匹配文件名
threshold: 10000, // 对超过10k的数据压缩
deleteOriginalAssets: false, // 不删除源文件
minRatio: 0.8 // 压缩比
})
)
// 用于根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
plugins.push(
new HashedModuleIdsPlugin()
)
// 开启分离js
config.optimization = {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 1000 * 60,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// 排除node_modules 然后吧 @ 替换为空 ,考虑到服务器的兼容
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
}
}
}
}
};
// 取消webpack警告的性能提示
config.performance = {
hints: 'warning',
//入口起点的最大体积
maxEntrypointSize: 1000 * 500,
//生成文件的最大体积
maxAssetSize: 1000 * 1000,
//只给出 js 文件的性能提示
assetFilter: function (assetFilename) {
return assetFilename.endsWith('.js');
}
}
// 打包时npm包转CDN
config.externals = externals;
}
return { plugins }
},
pluginOptions: {
// 配置全局less
'style-resources-loader': {
preProcessor: 'less',
patterns: [resolve('./src/style/theme.less')]
}
},
devServer: {
open: false, // 自动启动浏览器
host: '0.0.0.0', // localhost
port: 6060, // 端口号
https: false,
hotOnly: false, // 热更新
proxy: {
'^/sso': {
target: process.env.VUE_APP_SSO, // 重写路径
ws: true, //开启WebSocket
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true
}
}
}
}
复制代码