unplugin技术揭秘
前言
之前看了下unplugin-auto-import这个库,发现其实现vite、webpack的兼容是基于unplugin的,其实,兼容思路个人觉得不难,难的是如何接入
源码
核心思路
你当然可以暴露出一个函数,接收一个配置对象,指定一个type标识当前是运行与哪一个打包平台,然后配合if...else...去处理不同的逻辑;也可以分别打包出vite、webpack的单独文件,然后配置exports导出,但其实,还可以更好
仍是导出函数,接收配置对象,但是不需要设置if...else...分支,也不需要配置exports,而是利用对象的get属性来转发到不同的目标下做处理,如此,便可以针对不同的平台做单独的处理了
平台化
vite与rollup
从生产构建的角度来说,vite即rollup,因此可以视作一起处理
如上,框红一的位置,对rollup做扩展,使其支持transformInclude和loadInclude这两个过滤接口
框红二的位置,则是对vite或rollup特有的部分做提取合并,也就是对应了如下框红位置的写法
esbuild
esbuild的核心是setup函数,相关的api接口也是通过该函数导出的
这意味着,必须做一层转换处理,根据传入的hook手动调用esbuild的同功能接口
另外,在transform阶段会对源码做改动从而破坏原有的sourceMap,需要进行相关处理
如下,借助@ampproject/remapping来完成sourceMap的合并生成
最后还要重新生成映射地址
正如注释写的一样,为esbuild兼容toString和toUrl接口,避免出错
webpack
webpack不直接接受对象形式,而是要以apply接入
本质上还是根据用户填写的hook去调用webpack的具有相同功能的钩子函数
webpack在plugin之外又提取了loader的概念,一般来说,plugin用于完成某个功能,loader用于对源码进行矫正,因此,需要在plugin中动态的对源码类型的操作做转发,如load和transform
对于非源码操作的,则在plugin自身完成即可
因为分离出来了两个体系,因此要有一种所谓通信的机制,让plugin和loader都知道当前是谁在接手这部分工作