420 - 《手撕源码 34:rolldown(上)》
发布于 2024年3月11日
rolldown 刚出,翻下代码。个人感觉一个库刚写出来时是看他的最好时机,因为没考虑那么多的边界场景,复杂度相对较小,看起来轻松。
1、目录结构和代码流。
重要的包的目录结构如下。
+ crates
+ rolldown
+ rolldown_binding (@rolldown/node-binding)
+ ...
+ packages
+ node (@rolldown/node)
+ ...
如果从 JS 入口开始看,代码的调用路径是 packages/node > crates/rolldown_binding > crates/rolldown 。
packages/node 提供 rolldown
和 experimental_scan
两个方法。前者会调 rolldown_binding 的 write
方法;后者会调 rolldown_binding 的 scan
方法,盲猜之后会结合插件给 vite 做依赖 scan 使用。
crates/rolldown_binding 是基于 napi 对 crates/rolldown 的接口封装,提供了 scan
、write
和 generate
方法,用 Mutex 加锁以避免被同时调用。同时 plugins 配置会被转成 JsAdapterPlugin。
2、rolldown crate 的整体设计。
看下来感觉整体思路应该是参考着 rollup 做的,上次看 rollup 代码已是很久以前,181 - 《手撕源码 25:Rollup 3 上》,忘差不多了。
主入口在 crates/rolldown/src/bundler.rs 的 bundle_up 方法,构建分三个 stage,分别是 scan、link 和 bundle。后一个 stage 基于上一个 stage 的输出作为输入,很好理解整体的逻辑。
scan stage 会找到所有模块。基于 ModuleLoader 实现,利用 tokio + XXXM