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