这篇文章继续我们的‘跨平台’之旅, 之前我们聊过:
- 编写‘跨版本’ 的组件库: 如何实现支持跨 Vue 2/3 的组件库
- 编写‘跨框架’的组件:来一瓶 Web Component 魔法胶水
- 跨平台的运行容器: 使用 Docker 实现前端应用的标准化构建、部署和运行
- 编写跨运行时的程序
今天继续来聊一下怎么编写‘跨平台’的构建插件,前端构建工具一直都是一个比较卷的赛道,毕竟它是前端工程化的重要一环,此时此刻它正在经历着新一轮的变革 —— 使用系统编程语言(如 Rust、Go) 重构。
从 Webpack、Parcel,到 Vite, 再到 Turbopack、Rspack、Bun… 百花齐放。
那问题又来了,新的构建工具出来,意味着又有新的“技术债”产生。
在这个技术快速发展的时代,新旧并存的局面没办法避免。作为库的开发者,我们希望我们的库能够服务更多的人,那“跨平台”是我们不得不考虑的问题。
怎么开发一个跨平台的构建插件呢?
首先我们要站在更高的角度审视这些构建工具,这些构建工具主要做什么工作?从它们暴露的插件 API 中抽象共性。这些构建工具目的都是一致的,无非就是:
- 文件预处理/转换。比如 sass、typescript、image、icon 等,前端需要处理的各类资源的处理
- 依赖关系处理。解析和处理模块之间的依赖关系
- 代码输出。包含代码合并、代码优化、产物输出等。
主要的差异点无非就是实现不同,进而在扩展性、构建性能上面也会有不同的表现。
接下来我们就挑两个目前比较主流的构建工具来喵喵看,我挑选的是 Webpack
和 Rollup
( Vite 也是基于 Rollup 的,两者差异不大)。
Webpack
尽管这几年受到了 Vite 等方案的挑战,但不得不承认,Webpack 依旧是王,至少在生态和存量市场上。
Webpack 是基于事件驱动
(Event Driven) 的插件式
编译器。Webpack 就是一个非常典型的微内核
架构, 可以说 Webpack 的内核就是 Tapable
,非常小、非常优雅。非常值得我们去反复咀嚼研究
几乎所有的功能,不管是内置的、还是第三方的都是通过插件的形式实现。包括我们看到的所有的 webpack 配置, 都会被解析转换成相应的插件,而配置不过是方便用户使用的用户界面
罢了
Webpack 通过 Tapable Hooks
暴露了丰富的生命周期钩子,支持开发者对编译器、模块查找、文件转换、优化、产物生成的每一个细节进行定制。