zoukankan      html  css  js  c++  java
  • pre-commit + imagemin 实现图片自动压缩

    我们日常开发的前端项目中,图片资源会占到项目资源的很大比例,因此在考虑到性能优化,页面加载速度的时候,如何更好地处理图片就非常重要了。

    首先我们可以想到的方案是:使用webpackimage-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! 
    ");
    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("
    ");
      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(/[
    	]/);
        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

  • 相关阅读:
    leetcode刷题四<寻找两个有序数组的中位数>
    leetcode刷题第三天<无重复字符的最长子串>
    leetcode刷题第二天<两数相加>
    leetcode刷题第一日<两数和问题>
    sqlalchemy.exc.ProgrammingError: (pymysql.err.ProgrammingError)
    flask微电影系统开发中上下文处理器
    gdb解决字符串打印果断措施
    邻接表
    Jarvis OJ 一些简单的re刷题记录和脚本
    windows控件理论学习
  • 原文地址:https://www.cnblogs.com/dora-zc/p/12643123.html
Copyright © 2011-2022 走看看