pre-commit + imagemin 实现图片自动压缩
dora_zc 人气:1
我们日常开发的前端项目中,图片资源会占到项目资源的很大比例,因此在考虑到性能优化,页面加载速度的时候,如何更好地处理图片就非常重要了。
首先我们可以想到的方案是:使用`webpack`的`image-webpack-loader`来压缩图片。但是这种方案有个弊端,就是`webpack`每次构建的时候都要处理一次图片压缩,会影响到`webpack`的构建速度。
接下来要讲的是 `pre-commit` + `imagemin` 实现的图片自动压缩方案,思路是在我们`git commit` 时,将要提交的图片文件替换为压缩后的文件。
## 安装依赖
```
npm install pre-commit imagemin imagemin-pngquant -D
```
## 修改 package.json
```
// package.json
{
....
"scripts": {
"imagemin": "node imagemin.js"
},
"pre-commit": [
"imagemin"
],
}
```
## 在项目根目录下新建 imagemin.js
```js
const execSync = require("child_process").execSync;
const path = require("path");
const imagemin = require("imagemin");
const imageminPngquant = require("imagemin-pngquant");
console.log("pre-commit hook start imagemin! \n");
let diff = getDiffFiles();
compressPics(diff);
function getDiffFiles(type) {
// pre-commit钩子本身不传递参数
//https://git-scm.comhttps://img.qb5200.com/download-x/docs/githooks/1.7.4#_pre_commit
// 所以通过git diff 命令拿到本次提交涉及的变动文件
let root = process.cwd();
let files = execSync("git diff --cached --name-status HEAD")
.toString()
.split("\n");
let result = [];
// add, delete, modified, renamed, copied
type = type || "admrc";
let types = type.split("").map(t => {
return t.toLowerCase();
});
files.forEach(file => {
if (!file) {
return;
}
let temp = file.split(/[\n\t]/);
let status = temp[0].toLowerCase();
let filePath = root + "/" + temp[1];
let extName = path.extname(filePath).slice(1);
if (types.length && ~types.indexOf(status)) {
result.push({
status: status, // admrc中的一个
path: filePath, // 绝对路径
subpath: temp[1], // 相对路径
extName: extName // 扩展名
});
}
});
return result;
}
function compressPics(files) {
let pngs = files.filter(
file => file.extName === "png" && ["a", "m"].includes(file.status)
);
console.log(pngs);
let parentFolder = {};
pngs.forEach(x => {
// 根据不同父级目录分类
let pf = x.subpath.slice(0, x.subpath.lastIndexOf("/"));
parentFolder[pf]
? parentFolder[pf].push(x.subpath)
: (parentFolder[pf] = [x.subpath]);
});
for (let pf in parentFolder) {
imagemin(parentFolder[pf], {
// 原图片目录
destination: pf, // 生成图片的目录
plugins: [
imageminPngquant({
speed: 1,
quality: [0.4, 0.5]
})
]
})
.then(res => {
console.log(res);
execSync("git add . ");
})
.catch(err => {
console.log(err);
process.exit(1);
});
}
}
```
## 提交图片
执行 `git commit` 命令后,如果检测到有 `png` 格式的图片,会进行压缩处理后再提交。
![](https://img2020.cnblogs.com/blog/1449188/202004/1449188-20200406173732558-306914277.png)
我们把已经提交过的 `pic.png` 重命名为 `pic1.png`,不会再次进行压缩。
![](https://img2020.cnblogs.com/blog/1449188/202004/1449188-20200406173758759-1665444671.png)
## 图片压缩后的效果
原来的图片大小 3.2M
![](https://img2020.cnblogs.com/blog/1449188/202004/1449188-20200406173817725-538942497.png)
压缩后 695.28kb
![](https://img2020.cnblogs.com/blog/1449188/202004/1449188-20200406173835859-780393612.png)
加载全部内容