前端工程化的未来
目前绝大多数前端应用都是基于 webpack bundler + babel compiler,绝大多数人掌握的也是它们。
这是前端稳定高速发展十年中的中流砥柱。
优化
在发展过程中,源源不断的讨论、文章、轮子出现、消失,其实大多仍然不会脱离 js 语言。
本质仍然是基于构建工具(bundler、compiler)不断的做优化、重写,这包括
- 冷启动、热更新,3000-5000 modules 项目的生产构建
- 编译速度优化,将 babel-loader 替换为 esbuild transform、swc-loader
- mfsu 编译分离
- 体验优化,开发开箱即用
- vue-cli
- father
- 持久化缓存 persistent cache(将构建结果缓存在磁盘)
- 分布式构建缓存共享(未来)
由于webpack的构建速度、热更新、code spliting、treeshaking等问题,产生了 vite。
vite
vite 诞生的理由其实并不是想解决生产的 bundle 问题,而是 dev 阶段的体验问题,所以没有造 bundler 的轮子。
其次,dev 与 build 过程与产物是不一致的,如果项目有3000-5000个modules,冷启动时压力全都来到了浏览器端,即使有 pre-bundle(依赖预构建),本地网络请求+解析依旧会很慢。
vite 本身是一层 api 包装,并不具备打包能力,仍然使用 rollup 打包,compiler 默认使用 esbuild。
![](https://raw.githubusercontent.com/yangm86/blog-image/main/2024-07-10/the_parsed_crop_image.1720613638764.png)
所以这也导致,rollup存在的问题,vite都存在,比如 module federation 的支持。
在那时候,esbuild 诞生,但是其 api 架构设计,使得扩展性比较差。
![](https://raw.githubusercontent.com/yangm86/blog-image/main/2024-07-10/the_parsed_crop_image.1720613668013.png)
这其中的平衡是每一个框架或库都存在的问题,因为好用和可扩展性是不可兼得的。
Simple API is useful for adoption but maybe hard for scaling.
为了解决上述问题,vite 也正在自己开发 bundler:rolldown。
swc
swc的诞生只是想提高 js 的compiler 速度,但是仍然没能脱离 webpack 或 rollup。
但是 swc 的使用问题较多,且是开源项目,基本上只有作者一人在支持(今年多了一个),目前生产的实践稳定性还不够。
![](https://raw.githubusercontent.com/yangm86/blog-image/main/2024-07-10/the_parsed_crop_image.1720613688506.png)
但是最近,官网的文档更新定位为:支持 compiler 和 bundling,并且 swcpack 正在开发中。
rspack
由于字节的体量大,业务多,最开始也是尝试 esbuild、webpack、vite、rollup 各种组合,但都不能满足业务需要,一步一步演变成了今天的 rspack。
架构(api)是基于 webpack 实现,基本可以理解为 webpack 的 rust 实现。
rspack 是基于大量业务沉淀出来的,目前来看是可以在业务中实施。
但本质,其第一要务是服务于字节内部的商业业务,未来存在很大的不确定性(相似的例子 eggjs等)。
webpack 配置很多,所以有了开箱即用的 vue-cli。
同理,rspack 对应上层封装 rsbuild,单独的 api 和插件体系(类似 esbuild)。
rust
可以看到主流的底层构建已全面拥抱 rust,且javascript相关生态也趋于完善:
- oxc - 一系列js生态工具的集合 https://github.com/oxc-project/oxc/tree/main/crates
- biome - linter 和 formatter
我们学习 rust 的主要目的是为了迎接接下来新的技术变革,其中最重要的是更新我们以 webpack + babel 为技术基础的工程化相关知识。
题外话
- 另外babel-loader 和 swc-loader 的 AST 是基于 estree AST 做了魔改,并不是标准的 estree https://github.com/estree/estree。
- 模块联邦(v2)的深度使用,可以解决公司内部的资产共享与版本控制的问题(cdn无法满足)。
阶段性目标
学习 rust 的第一个目标被设定为,能够像利用 babel 提供的插件机制或工具函数进行 AST 操作一样,使用 crates 操作 AST。