最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Webpack中loader的编译缓存

    正文概述 掘金(桔子哥)   2021-03-20   442

    编程界常见的两大“换”:【用时间换空间】与【用空间换时间】。

    用时间换空间,常见于网络通信时对传输内容的编码和压缩,通过发送端花费计算时间编码、压缩和接收端花费计算时间解码、解压缩,减少传输内容体积,从而达到整体效率最优。

    用空间换时间,常见于把需要较长I/O时间或者昂贵计算才能得到的资源或者计算结果进行缓存,当下次使用时可以直接使用缓存,花费存储空间来节约时间,提高处理速度。

    在Webpack的编译过程中,就可以通过对编译结果进行缓存而提升构建效率。

    之所以聊到这个话题,是因为最近工作中碰到了一个问题:我需要配置less-loader的modifyVars选项来修改ant-design的样式类前缀,结果配置完了后在本地dev时死活都不生效。排查过后发现,是因为项目内 cache-loader 的编译缓存导致的浏览器拿到的样式内容仍然是旧的。删掉缓存后重新启动devServer就解决问题了。

    先声明一点,以下讲到的内容均以Webpack 4为例;而Webpack 5已经内建了编译缓存的能力,并且 cache-loader 已弃用。

    在Webpack中,主要对 js 和 css 的编译结果进行缓存:

    • babel-loader 已经集成了编译缓存能力
    • 样式处理中,可自行添加 cache-loader 处理

    那么 cache-loader 和 babel-loader 是怎么如何判断应该命中缓存,还是应该重新编译并更新缓存呢?

    cache-loader

    缓存文件名称中的hash值是判断是否命中的重要标志,cache-loader 计算hash值的过程及其相关数据来源为:

    Webpack中loader的编译缓存

    从图中可看出,hash值是由3个要素确定:

    • 当前 cache-loader 的版本号
    • process.env.NODE_ENV
    • request字符串

    看到这里读者或许会疑问:在修改less文件后,cache-loader 是如何知道应该更新缓存的呢?

    实际上,cache-loader 会在loader链执行的 pitch阶段 检查所要编译的目标文件的mtime,即文件的最近修改时间;而之前的缓存文件中保存了上次编译时目标文件的mtime,将两个mtime进行对比即可知是否需要重新编译了。

    因此上面提到的修改 less-loader 的 modifyVars 后,拿到的样式仍然来自旧缓存的原因是:

    • antd的less文件没有改动,因此其文件的mtime未变
    • 缓存文件名的hash值也未变

    babel-loader

    babel-loader 生成缓存文件时,文件名中hash值的计算过程,在 babel-loader/lib/cache.jsfilename() 中:

    const filename = function (source, identifier, options) {
      const hash = crypto.createHash("md4");
      const contents = JSON.stringify({
        source,
        options,
        identifier
      });
      hash.update(contents);
      return hash.digest("hex") + ".json";
    };
    

    计算hash的三个要素为:

    • source:编译目标的源代码字符串
    • options:babel的编译选项,例如编译目标的文件路径、插件集合plugins、所用预设presets等
    • identifier:一个对象的序列化值,具体如下
    identifier = JSON.stringify({
      options, // 跟上面的options是同一个对象,即babel的编译选项
      "@babel/core": transform.version, // 所调用babel的版本号
      "@babel/loader": version // 当前babel-loader的版本号
    })
    

    综合上面来看,babel-loader在计算缓存hash时涉及到了编译目标的源码、编译选项、所用babel的版本、当前babel-loader的版本等要素,覆盖面还是比较全的,能够保证当修改了代码、改变了编译选项时能够重新触发编译。


    起源地下载网 » Webpack中loader的编译缓存

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元