pre-commit + imagemin 實現圖片自動壓縮
- 2020 年 4 月 6 日
- 筆記
我們日常開發的前端項目中,圖片資源會佔到項目資源的很大比例,因此在考慮到性能優化,頁面載入速度的時候,如何更好地處理圖片就非常重要了。
首先我們可以想到的方案是:使用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
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.com/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(/[nt]/); 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
格式的圖片,會進行壓縮處理後再提交。
我們把已經提交過的 pic.png
重命名為 pic1.png
,不會再次進行壓縮。
圖片壓縮後的效果
原來的圖片大小 3.2M
壓縮後 695.28kb