449 - 《从 0 实现 Rust 构建工具》
本文是 2024.06.28 将在 SECon 上分享的主题的第二部分,先写个文字稿。
sorrycc/toy-mako 的仓库会在分享那天公开。
和大家分享下如何从 0 实现一个 Rust 构建工具,我把很多内容和功能都做了简化,让大家可以花 10 分钟大概理解一个构建工具的构成。如果你想自己实现一个,或者参与贡献,或者遇到问题有个大致的思路,了解构建工具的原理还是有必要的。
1、
首先,我们需要一点前置知识。分两部分,1)Rust 语言基础,2)前端构建领域知识。当然,如果不会 Rust 也没关系,这里不涉及具体语法,用 JS 也可以完成,只是使用到的相关依赖时需要替换为 JS 生态的版本。
2、
如果你是 Rust 0 基础,关于如何学 Rust,我有一些建议。个人的经验是 B 站视频快速打底,推荐下这个 B 站频道的免费课程,这是对应一本书的视频讲解,我个人和身边的一些同事都是先 2 倍速快速过完他,对整体的 Rust 体系会有个整体的了解;然后再看电子书时就比较顺畅,通过电子书做系统学习和深入;再就是多实践,不写容易忘,肯定每个人身边都有一些学过 N 边 Rust 的同学吧;最后,遇到不懂可以问身边会 Rust 的同学,或者 AI。
3、
再就是「前端构建」的领域知识了。关于这部分,Google 出的 bundlers.tooling.report 上有详细介绍,我对此做了一些梳理,同时补充了一些个人觉得应该需要的点。
4、
先看一下 Mako 完整的构建流程,主要分两个阶段,Build 和 Generate。其实大部分构建工具都大同小异,Esbuild、Farm、Webpack 等,基本都是这个流程,做的功能也都类似,只是取名、顺序、整体设计、边界场景处理、特色功能、业务场景等方面可能有所不同。
Build 阶段的输入是文件列表和配置,输出是模块图谱;Generate 阶段的输入是模块图谱,输出是以 chunk 为维度的代码,以及和这个代码相关的 sourcemap、manifest 等。
5、
如果大家用过 Webpack,应该都有配置过入口文件,而 Build 阶段的输入就是入口文件,输出是一个模块图谱。由于文件可能存在依赖,我们需要一个队列来保存它。而要输出模块图谱,我们需要对每个进入到队列的文件做 load、parse、transform、analyze deps 和 resolve 等操作。
6、
然后把中间这个过程拆