写了一之后好像鸽了挺久的,上一篇写完之后其实这个初始化模版的项目文件已经差不多写完上传到github仓库了,上一篇末尾也把地址放上来了,emmm,再放一下吧,vue初始模板。
现在趁着周末到了补一下(二),写一下其中webpack插件的引入。之后如果还要完善,那就只能引入momentjs,imutablejs之类的,那这些其实就看个人的编码习惯跟喜好了,有些人可能喜欢,有些人可能就觉得这些没有必要。可能的话,之后再写一篇全景视频的实现,及其对接hls与flv直播流,rtmp的话因为是flash协议,非原生h5video接收,没有头绪,就没对,代码已上传至仓库。vue-vr
进入正题吧,因为是连续写完的,那么就基于上一篇的配置接着继续完善。没看过一的建议去看一下吧,这样对整体也会有一个比较清晰的印象,vue-cli4项目初始配置及优化(一)。
这个插件能够在打包的时候压缩图片,我在写的时候测试了一下,引入了六张图片,总大小为13.9mb,打包后为4.62mb,直接减少了3分之二的大小,效果显著,十分好用。
cnpm安装,这里提醒一下,因为墙的缘故,如果没有,请用cnpm或是其他源安装,因为它的依赖库很有可能,不,99%会安装失败,这个我在上一篇配置(一)里面已经讲过了,但还是要强调一下,务必用cnpm安装,我当时就给搞的心态都崩了,没注意npm安装信息,找了半天错,结果是依赖库没装上:
cnpm i image-webpack-loader -D
那么配置的话,在vue.config.js中配置webpack,如下
const IS_PROD = 'production'.includes(process.env.NODE_ENV)
module.exports = {
chainWebpack: config => {
if (IS_PROD) {
// 作用:压缩图片
// 测试:图片总大小13.9mb,
// 引入前项目打包后img文件夹大小为13.9mb,引入后img文件夹大小为4.62mb
// 压缩比达33%,图片资源大小减少了三分之二
// PS:建议cnpm安装, npm因为墙的原因可能安装不上一些依赖
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
mozjpeg: { progressive: true, quality: 65 },
optipng: { enabled: false },
pngquant: { quality: [0.65, 0.9], speed: 4 },
gifsicle: { interlaced: false }
// webp: { quality: 75 } 大大减少体积,但在ios存在兼容问题,不用
})
}
}
}
这个插件主要用于把多张icon图合并成一张,从而减少浏览器请求数,优化加载速度。
它会自动生成合成后的图片与可引用css文件,通过调用css文件中的不同类名呈现该图不同位置的图片。
安装:
npm i webpack-spritesmith -D
配置:
const path = require('path')
const resolve = dir => path.join(__dirname, dir)
const SpritesmithPlugin = require('webpack-spritesmith')
module.exports = {
configureWebpack: (config) => {
// 作用:将散落的小图icon之类的组合生成雪碧图,减少浏览器请求次数,加快页面加载速度
config.resolve.modules = ['node_modules', './src/assets/img']
config.plugins = [...config.plugins, new SpritesmithPlugin({
src: {
cwd: resolve('./src/assets/img/icons'),
glob: '*.png'
},
target: {
image: resolve('./src/assets/img/sprite.png'),
css: [
[resolve('./src/assets/scss/sprite.scss'), {
// 引用自己的模板
format: 'function_based_template'
}]
]
},
customTemplates: {
function_based_template: templateFunction
},
apiOptions: {
cssImageRef: '~sprite.png'
},
spritesmithOptions: {
padding: 20
}
})]
}
}
var templateFunction = function (data) {
var shared = '.icon { background-image: url(I);background-size: Wpx Hpx;}'.replace('I', data.sprites[0].image).replace('W', data.spritesheet.width)
.replace('H', data.spritesheet.height)
var perSprite = data.sprites.map(function (sprite) {
return '.icon-N { width: Wpx; height: Hpx; background-position: Xpx Ypx; }'
.replace('N', sprite.name)
.replace('W', sprite.width)
.replace('H', sprite.height)
.replace('X', sprite.offset_x)
.replace('Y', sprite.offset_y)
}).join('\n')
return shared + '\n' + perSprite
}
target中是生成后的图片及css存放位置,customTemplates中是自定义生成图片的方法,不清楚,可以打印出来看一下。
使用方法:
生成的css文件在frame.scss引用,
@import'@a/scss/sprite.scss'
然后就可以在任何地方使用icon图了
<div class="icon icon-每个小图的名字"></div>
效果如图:
用于压缩项目文件大小,开启gzip压缩并打包之后项目体积压缩的也挺夸张的,280kb给我压缩到48kb,也是我必导入的一个插件。
该插件需要服务器端配置,如下,安装nginx后,编辑nginx.conf文件,在http中插入下面这一段gzip配置语句:
http {
# gzip配置
gzip on;
gzip_static on;
gzip_min_length 10k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 8;
# 根据需要添加文件类型
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
# ...其它配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server{
listen 443 ssl http2;
......
}
......
}
然后重载一下nginx服务
service nginx reload
ok了,其实配置完服务器之后就已经开启网站压缩了,哪怕前端不引入这个插件,nginx也会自动去压缩网站文件,区别其实就是如果前端这边打包时已经生成了压缩文件,nginx会直接拿给浏览器,如果没有,nginx会压缩之后再传给浏览器,那么就省去了这一段压缩的时间,所以,该导入还是要导入的。
安装:
npm i compression-webpack-plugin -D
配置:
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: (config) => {
// 打包gzip压缩
config.plugins = [...config.plugins, new CompressionWebpackPlugin({
filename: '[path].gz[query]', // 旧版本为assets,现为filename
algorithm: 'gzip',
test: /\.js$|\.css$|\.jpg$/,
threshold: 10240,
// deleteOriginalAssets: true, // 删除源文件,不建议开启
minRatio: 0.8
})]
}
}
这里面要注意的是deleteOriginalAssets这一项,我是不建议开启的,因为nginx如果没有开启gzip压缩,是拿的未压缩的源文件,这时就会出问题,不删除更保险一点,无论nginx有没有开启gzip压缩,都能返回网站文件。
部署到服务器后访问效果如图,如果看到Content-Encoding里的gzip,那么就已经开启gzip压缩
这个插件主要是用于打包过程中的一些压缩优化,但是由于webpack内置了splitChunks(之后会写到),所以这里引用只是为了去除console.log。没错,再也不用删除项目中的console了,打包自动去除。
安装:
npm i uglifyjs-webpack-plugin -D
配置:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
configureWebpack: (config) => {
// 打包优化,去除console.log
config.optimization.minimizer.push(new UglifyJsPlugin({
sourceMap: false,
// 开启多线程提高打包速度, 默认并发运行数:os.cpus().length - 1
parallel: true,
uglifyOptions: {
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 生产环境自动删除console
},
warnings: false
}
}))
}
}
配置splitChunks(webpack4内置), 将公用组件,样式,依赖等等提取出来,减少打包体积。
配置:
module.exports = {
configureWebpack: (config) => {
config.optimization.splitChunks = {
cacheGroups: {
common: {
name: 'common',
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
reuseExistingChunk: true,
enforce: true
},
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
priority: 2,
reuseExistingChunk: true,
enforce: true
},
elementUI: {
name: 'elementui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
chunks: 'all',
priority: 3,
reuseExistingChunk: true,
enforce: true
},
echarts: {
name: 'chunk-echarts',
test: /[\\/]node_modules[\\/](vue-)?echarts[\\/]/,
chunks: 'all',
priority: 4,
reuseExistingChunk: true,
enforce: true
}
}
}
}
}
打包分析软件,能够看到打包后的各模块大小,非常直观。
安装:
npm i webpack-bundle-analyzer -D
配置:
module.exports = {
configureWebpack: (config) => {
// 打包分析
config.plugins = [...config.plugins, new BundleAnalyzerPlugin(
{
analyzerMode: 'server',
analyzerHost: 'localhost',
analyzerPort: 10000,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: false,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
logLevel: 'info'
})]
}
}
PS:stylint就不讲了,好像有点冲突,引入后webpack别名失效,导致一堆报错,其实就是类似于eslint的插件,校验样式的,支持各css预处理器,然而对我而言作用并不大,有需求的可以自行看我仓库,在vue.config.js中,注释掉了,还有一个stylint.config.js文件,类似.eslintrc.js,存储校验规则。