技术文章

前端编译器babel的缓存机制是怎么做的?

babel简介

babel是一个js的编译器,我们平常使用的react、vue等框架都是通过它才能编译成浏览器可以执行的代码,个人感觉它是前端这座大厦最最底层并且是最最核心的部分。如果没有它,前端肯定会退回到刀耕火种时代。

既然是编译器,所以它肯定会去操作很多的文件,在babel/core中,它读取最多的是它的配置包括babelrc、pkgjson、插件、预设等文件,所以对操作文件的结果做缓存必不可少!

babel的缓存机制 假设我们现在处理的是一个文件

在js中做缓存容器常用的无非就是对象和数组,babel采用的是es6提供的map,其实就是一个对象,只不过它的key比较随意(不限于字符串)。

好了,现在既然有了缓存容器(map),那么key是什么呢?用于标记一个文件,一般可以选择用文件的路径和文件名+文件内容的md5值,babel用的是前者。

处理文件的过程可以定义一个handle方法,文件路径是handle的一个参数,有时仅仅一个文件路径并不能满足业务逻辑,需要传入其他的参数,所以handle拥有第二个参数。

在这里,babel对第二个参数做了一层封装,把它做成了一个有状态管理能力的对象CacheConfigurator,所以handle的第二个参数就是这个对象。

前端编译器

handle处理后就会得到对某个文件本次的处理结果value,现在就把value存入map中吗?sorry,并不是!

CacheConfigurator是一个拥有状态管理能力的对象,在handle处理的过程中是可以对它进行状态修改的。在得到value的值后,还需要去鉴别CacheConfigurator的状态。

前端编译器

CacheConfigurator有三种状态:

红色字体的valid是校验函数

never,无需缓存

forever,需要缓存但是下次再处理这个文件时跳过校验部分直接返回value

valid,下次再处理这个文件时需要走校验逻辑valid

那么这个校验逻辑是怎么传入的呢?

前端编译器

没错,就是handle在处理CacheConfigurator时传入的。

当下次再去处理这个文件时,就会优先走缓存的逻辑,只有校验通过才会直接返回value!

前端编译器