目的
webp的优势我就不说了,现在的需求就是老项目给所有图片打包成webp格式的,同时考虑兼容性,所有webp格式以及原图片格式都的保留一份
方案
nginx转发方案
通过打包一套静态图片,用nginx转一次,这个最简单,无论css还是js图片拦截代理到webp图片地址,你的项目代码一句不用改
生产环境配置方案
imagemin-webp-webpack-plugin推荐这个插件,使用简单
const ImageminWebpWebpackPlugin= require("imagemin-webp-webpack-plugin");
module.exports = {
plugins: [new ImageminWebpWebpackPlugin()]
};
但是如果你在css中用到{ background-image: url('../images/icon.webp'); },因为此时你的开发环境并没有这张图片,会报资源找不到的错误
1.建议css中使用自己找得到的图片{ background-image: url('../images/icon.png'); },通过给--生产环境下-- 配置css-loader webpcss,再打包一套css
这个loader的逻辑也很简单,用到背景图片的地方就给多打了一套类名 .webp的样式
/* Source */
.icon { background-image: url('../images/icon.png'); }
/* Result */
.icon { background-image: url('../images/icon.png'); }
.webp .icon { background-image: url('../images/icon.webp'); }
//webpack.pro
const webpcss = require('webpcss').default;
postcss: {
plugins: [
webpcss({
webpClass: 'html.webp',
noWebpClass: ''
})
]
}
2.自己先打包一套图片到相应文件夹下面
开发环境配置方案
imagemin imagemin-webp
这两插件配合一下,写个简单的node程序,我这里是dev环境就打图片一次到src/assets下面,在相同的目录下生成一套webp格式的文件
1.在文件目录下新建一个webpmin.js文件,
/*
imagemin 用来压缩图片的 例子是7.0.1这个版本
imageminWebp 一个插件,用来吧图片转成webp
path NodeJS ’path’ module
默认imagemin,在多目录情况下是不保存目录结构的,有可能新版本会支持吧
使用最终你的destination决定输出文件夹
基本逻辑就是拿到所有的文件夹路径,遍历去写入到相应的文件目录下
*/
const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');
const path = require('path');
(async () => {
//拿到满足匹配规则的文件信息 file sourcePath destinationPath
const files = await imagemin(['src/assets/**/*.{jpg,png}'], {});
/*
自定义目录 打包到源文件夹目录 让destinationPath等于sourcePath就可以了
*/
files.map(item => {
let sourcePath = item.sourcePath
let destinationPath = path.dirname(sourcePath)
imagemin([sourcePath], {
destination: destinationPath,
plugins: [
imageminWebp({
quality: 75
})
]
});
})
})();
2.node webpmin.js 命令执行就行了
3.也可以在package.json把命令加进去
"scripts": {
"dev": "node webpmin.js&&vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"webpmin": "node webpmin.js",
},
- src/assets 有相应的文件了,就好办了
css 背景图片可以手写写一套兼容的样式,不想手写的话,下面的cssloader也能自己打包一套样式进去
逻辑用到背景图片的地方就给多打了一套类名 .webp的样式
/* Source */
.icon { background-image: url('../images/icon.png'); }
/* Result */
.icon { background-image: url('../images/icon.png'); }
.webp .icon { background-image: url('../images/icon.webp'); }
const webpcss = require('webpcss').default;
postcss: {
plugins: [
webpcss({
webpClass: 'html.webp',
noWebpClass: ''
})
]
}
js中也可以写自定义指令去根据浏览器替换webpc
Vue.directive('webp', {
bind: function (el, binding) {
var img = new Image();
img.onload = function () {
if (img.height > 0 && img.width > 0) {
el.src = el.getAttribute('data-webp');
} else {
el.src = binding.value;
}
};
img.onerror = function () {
el.src = binding.value;
};
img.src = el.getAttribute('data-webp');
}
});
使用
<img v-webp="image.png" data-webp="image.webp" />
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END