towebp-loader诞生记~ 一个webpack 图片loader
2017-03-21 08:55
591 查看
http://www.jianshu.com/u/9760e0846302
在上篇Vuejs webp图片支持,插件开发过程~ 中我做了一个图片转换成webp的组件,并且使用了相关的loader,但是我们在使用过程中发现webp和原图的hash是不一样的,这样我们就没有办法保留版本的概念了,临时我使用时间戳来作为替代,但是这样每次上传都会重新上传所有文件,有点浪费硬盘,于是我今天做了这个
支持url的
vue-webp
使用方法
主要代码都在这里了。还有一些webpack loader的API 大家仔细去读相关文档
webp-loader
url-loader
file-loade
本人已经使用vue.js半年多了,在做一些Html5页面的时候发现很多页面都是图片组成的,如果能有效的压缩图片的体积那么整个项目体积就会减少很多,这是为什么写这个简单东西的起点。
Webp 百度百科上已经讲清楚在保持原画质的情况呀体积可以压缩到原来的60%这是很牛逼的一件事。看看webp的兼容情况,下图是caniuse上面最新的webp支持情况
webp兼容情况
兼容情况还是不那么乐观,不过chrome和安卓阵营已经全部支持。所以我还是做了这件事。
这时候就非常简单了指令在
然而事情的这个时候发现一些小的图标不见了,原来我的
所以最终我的更新代码是这样的
这个时候
这样我的
只有指令可不行,每次都要自己生成一份
具体使用方法可以参考我的 Vue.js 2.0 后台项目 模板项目
谢谢大家,看到这里。欢迎各种star
在上篇Vuejs webp图片支持,插件开发过程~ 中我做了一个图片转换成webp的组件,并且使用了相关的loader,但是我们在使用过程中发现webp和原图的hash是不一样的,这样我们就没有办法保留版本的概念了,临时我使用时间戳来作为替代,但是这样每次上传都会重新上传所有文件,有点浪费硬盘,于是我今天做了这个
towebp-loader。
功能
towebp-loader可以在webpack中根据图片类型转换成一份
webp和原图两份图片,并且集成了
url-loader的功能
支持url的
limit功能和
file-loader文件名的功能。
使用方法
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'towebp?' + JSON.stringify({ limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') }) },
配合vue-webp指令使用效果更佳哦
vue-webp使用方法
![](abc.jpg)
关键源码讲解
…… // 获取loader中的查询字符串 使用webpack loader api var query = loaderUtils.parseQuery(this.query); // 保存源文件的路径如果穿 name就使用不然使用默认hash.ext模式 var url = loaderUtils.interpolateName(this, query.name || "[hash].[ext]", { content: content, regExp: query.regExp }); // webp 文件的保存路径 var webpUrl = url.substring(0, url.lastIndexOf('.')) + '.webp'; // limit参数来自url-loader 如果小于这个值使用base64字符串替换图片 if (query.limit) { limit = parseInt(query.limit, 10); } var mimetype = query.mimetype || query.minetype || mime.lookup(this.resourcePath); if (limit <= 0 || content.length < limit) { return "module.exports = " + JSON.stringify("data:" + (mimetype ? mimetype + ";" : "") + "base64," + content.toString("base64")); } …… // 转换原图成webp imagemin.buffer(content, { plugins: [imageminWebp(options)] }).then(file => { // 保存原图 this.emitFile(url, content); // 保存压缩后的webp图片 this.emitFile(webpUrl, file); callback(null, "module.exports = __webpack_public_path__ + " + JSON.stringify(url) + ";"); }).catch(err => { callback(err); }); ……
主要代码都在这里了。还有一些webpack loader的API 大家仔细去读相关文档
参考
webp-loaderurl-loader
file-loade
本人已经使用vue.js半年多了,在做一些Html5页面的时候发现很多页面都是图片组成的,如果能有效的压缩图片的体积那么整个项目体积就会减少很多,这是为什么写这个简单东西的起点。
Webp 百度百科上已经讲清楚在保持原画质的情况呀体积可以压缩到原来的60%这是很牛逼的一件事。看看webp的兼容情况,下图是caniuse上面最新的webp支持情况
webp兼容情况
兼容情况还是不那么乐观,不过chrome和安卓阵营已经全部支持。所以我还是做了这件事。
源码github
Vue.js的自定义指令系统十分强大是我做这件事的根本原因之一,所以我的设想是在一个指令中传入图片链接,然后在页面渲染的时候根据浏览器是否支持
webp格式的图片选择下载那个图片,这里就需要判断浏览器是否支持
webp了,这里我用到的是
canvas方法,代码如下
var canUseWebp = (function() { var elem = document.createElement('canvas'); if (!!(elem.getContext && elem.getContext('2d'))) { return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0; } else { return false; } })();
这时候就非常简单了指令在
update的时候根据是否支持然后选择不同的图片
function update(el, option) { var attr = option.arg || 'src'; if (el.tagName.toLowerCase() === 'img' && option.value) { el.setAttribute(attr, option.value); } };
然而事情的这个时候发现一些小的图标不见了,原来我的
webpack配置中设置了小于
10k的图片使用
base64编码,
所以最终我的更新代码是这样的
function update(el, option) { var attr = option.arg || 'src'; if (el.tagName.toLowerCase() === 'img' && option.value) { if (option.value.indexOf('data:image') < 0) { var tmp = option.value.substring(0, option.value.lastIndexOf('.')) + '.webp'; el.setAttribute(attr, canUseWebp ? tmp : option.value); } else { el.setAttribute(attr, option.value); } } };
这个时候
vue.js 2.0发布了。我有针对 2.0版本做了支持,由于我的指令非常简单,所以代码很轻松
var isVueNext = Vue.version.split('.')[0] === '2'; if (isVueNext) { Vue.directive('webp', function(el, binding) { update(el, { arg: binding.arg, value: binding.value }); }) } else { Vue.directive('webp', { bind: function() {}, update: function(val, old) { update(this.el, { arg: this.arg, value: val }); }, unbind: function() {} }) } };
这样我的
vue-webp指令就算完成了。
只有指令可不行,每次都要自己生成一份
webp格式的图片,这太不友好了。我有查找一番,发现一个
webp-loader可以在
webpack打包和dev的时候自动生成相应的
webp文件,太好了。使用原作者的
webp-loader发现文件的
hash不一样,我又用
imagemin最新版本升级了一下,上传到
npm叫
webpn-loader(原谅我不会命名),
具体使用方法可以参考我的 Vue.js 2.0 后台项目 模板项目
谢谢大家,看到这里。欢迎各种star
相关文章推荐
- towebp-loader诞生记~ 一个webpack 图片loader
- Webpack-源码四,从源码分析如何写一个loader
- Webpack4教程 - 第二部分,使用loader处理scss,图片以及转换JS
- 详解webpack之图片引入-增强的file-loader:url-loader
- [js高手之路]深入浅出webpack教程系列9-打包图片(file-loader)用法
- webpack之file-loader加载字体、图片路径问题(八)
- webpack编译出错You may need an appropriate loader to handle this file type.
- 怎样写一个webpack loader
- webpack 编译图片文件 file-loader
- 手把手教你撸一个 Webpack Loader
- webpack 相关 loader、插件详解,带你完成一个进阶 demo
- Webpack4教程 - 第二部分,使用loader处理scss,图片以及转换JS
- 手把手教你撸一个 Webpack Loader
- [Poi] Use Markdown as React Components by Adding a Webpack Loader to Poi
- [js高手之路]深入浅出webpack教程系列9-打包图片(file-loader)用法
- 怎样写一个webpack loader
- (一)webpack配置loader,打包js和sass以及图片文件
- extract-text-webpack-plugin" loader is used without the corresponding plugin How to deal
- SDWebImage使用——一个可管理远程图片加载的类库