geeeger / blog

https://loofp.com
1 stars 0 forks source link

简易的前端工程构建加速原理 #42

Open geeeger opened 3 years ago

geeeger commented 3 years ago

最近需要做一些构建工作,主要是把图片自动生成组件。

于是写了个很挫的脚本,其大致就是通过获取图片路径,转换为base64,塞进ejs模板里并输出

glob('src/assets/*.svg', (err, list) => {
    list.forEach(svgPath => {
        const content = fs.readFileSync(svg, 'utf-8')
        fs.writeFileSync('example.vue', ejs.render(template, { base64:  Buffer.from(content). toString('base64')}))
    })
})

但是这样有一个问题,每次生成都会去读写,由于我们的项目有lint --fix,而模板写的并不规范,导致每次都会commit一大堆。

于是有了解决的办法,效仿其他构建工具,生成一个manifest来比对。

引入md5-file对文件进行md5计算,获得如下内容

{
  "assets/img/smile-inactive.svg":"d4e6295a7bf1af27fef83fc571aad356",
  "assets/img/smile.svg":"3ab3d2c89f6685dda4e0ceecce1cba1c",
  "assets/img/smile1-inactive.svg":"066953dc94fcbf3fa32007d260ef9d20",
  "assets/img/smile1.svg":"4cd32948ad5d5aa66777b39ae1049e9b",
  "assets/img/smile2-inactive.svg":"d7a385fb052146d0a5c767211943f7df",
  "assets/img/smile2.svg":"a6841f90c72ac0d0ad86fa0fdf89d974"
}

在每次执行构建的时候都计算一下,然后比对新旧两表的差异

// 不过大脑的diff算法
function diff(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  const set = new Set([...keys1, ...keys2]);

  const remove = keys1
    .filter(x => !new Set([...keys2]).has(x))
    .map(key => ({
      type: 'remove',
      path: key,
      md5: obj1[key]
    }));

  const add = keys2
    .filter(x => !new Set([...keys1]).has(x))
    .map(key => ({
      type: 'update',
      path: key,
      md5: obj2[key]
    }));

  const update = Array.from(set)
    .filter(x => obj1[x] !== obj2[x] && !obj2[x] && !obj1[x])
    .map(key => ({
      type: 'update',
      path: key,
      md5: obj2[key]
    }));

  return [...remove, ...add, ...update];
}

使用差异构建,一面可以提升速度,一面可以防止多余构建。