Rollup源码学习(一)

前言

Rollup,是一个相比Webpack更加轻量的打包工具,并且Vite的底层是依赖Rollup进行构建,因为我目前感觉Vite的源码看起来还有些许吃力,为了更好的学习Vite,所以决定先学习Rollup,本文是一个系列,主要是通过源码学习了解Rollup的内部运行流程,以达到高屋建瓴的掌握Rollup并可以从容的定制化我们的前端工程化的目的。

在本系列文章中,我们将会以简单的方式来探索,对于一些if分支,我将会选择性忽视(若它不会影响工具的主要运行流程,不过不会忽视一些重要的内容),从而降低阅读难度。

本系列文章会摘录部分Rollup的API进行阐述,但是不会做大自然的搬运工,请大家放心观看。

源码结构

Rollup提供了CLIJS API两种方式。

CLI相比JS API的话,它内部其实是处理了一些默认实现,我们平时几乎不会使用到Rollup的JS API。

关于CLI里面的内容,我们可以不用关注太多,只需要关注build命令到底完成了什么任务即可。

在cli中,一个是用于向系统注册脚本命令的入口文件,另外一个就是我们要关注的build命令的提供者。

我们在这一节中还不会阐述cli需要关注的内容。

Rollup的核心实现在src目录中,入口文件我们关注node-entry.ts,通过这个文件暴露出Rollup的主文件,rollup/rollup.ts。

主入口文件分析

主入口文件,最重要的是rollupInternal函数,在这里面开始处理任务。 以上代码,我折叠起来了两个比较核心的内容,一会儿我们再聊。

首先,Rollup将用户的配置内容进行了一些标准化(如填充默认值,多种配置格式的内容转为一致的配置内容),然后初始化了一个Graph类,这个Graph类是一个核心类,后面我们会开始逐步进行阐述。

然后定义了一个catchUnfinishedHookActions的函数,最后,定义了一个结果对象并向外界返回。

先看一下catchUnfinishedHookActions函数的处理逻辑: hookParallel是Rollup自己定义的一个标准的处理生命周期的逻辑,通过这些生命周期,插件能够得到通知,从而可以改变Rollup的默认行为实现一些团队自定义的业务逻辑定制。

若遇到构建错误的话,则对外抛出buildEndcloseBundle的生命周期,若正常构建则仅抛出buildEnd生命周期,有的同学可能会觉得奇怪,为什么不抛出closeBundle,会的,只是不在这个位置处理,待会儿我们会提到它。

接着,我们再看这个result对象的定义: 再看一下官方API的阐述: 这个对象就是API上提到的我们需要自行处理的内容。

close函数里面触发了closeBundle的生命周期,这就是之前为什么正常执行的时候没有触发closeBundle的原因。

然后就是handleGenerateWrite函数的实现了。

在这儿主要是调用Bundle类的generate方法,Bundle类也是一个核心类,后面我们会着重讲它,调用generate主要的目的是将打包的内容进行生成。

暂时先不管write的if分支。

这个函数返回的是即将需要输出的内容,暂时也不用管。

接着就是if分支的内容,根据打包得到的Chunk,生成可以写入的内容,然后触发writeBundle生命周期。

关于Chunk类,它是Rollup的核心类,在后文我们还会着重进行分析。

到这个位置,Rollup的主入口文件已经分析的差不多了。

CLI的build完成了什么逻辑?

刚才我们已经提到过,如果直接调用Rollup的JS API,我们得自己去调用Rollup的返回对象,完成打包内容的写入、资源清理等逻辑,但是我们平时基本上都是使用的Rollup提供的命令行API进行的构建工作,接下来就看一看Rollup的CLI给我们内置了什么样的处理逻辑。

先看一下Rollup提供各种命令的主文件,我们直接找到Rollup调用build命令的位置: 在这个作用域的时候,是已经读取到了配置文件了,接着看一下配置文件是怎么读取到的。 如果配置了配置文件的路径,以直接解析配置文件的内容,否则就尝试读取命令行参数,这个逻辑不复杂,也很好理解,文中不再做详细阐述,有兴趣的同学自行查看源码。

然后,读取到了配置选项,就真正开始调用Rollup提供的JS API了。 将构建内容写入到命令行进行输出的场景我们用不到,所以这个代码就折起来不看了,Rollup在这个位置调用了打包内容写入到磁盘的操作,这儿调用的即是之前我们在解释主入口文件时候的那个handleGenerateWrite方法,读者可以向前翻阅一下它所完成的逻辑。

结语

到现在还是平平无奇的内容,下一篇文章开始,我们会建了一个项目给Rollup进行打包,将会采用断点的形式查看堆栈调用信息从而研究它的运行流程,未完待续......

相关推荐
自由鬼15 分钟前
正向代理服务器Squid:功能、架构、部署与应用深度解析
java·运维·服务器·程序人生·安全·架构·代理
沐森35 分钟前
对于electron编译和运行上的依赖解释
架构
袁煦丞35 分钟前
【局域网秒传神器】LocalSend:cpolar内网穿透实验室第418个成功挑战
前端·程序员·远程工作
江城开朗的豌豆36 分钟前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js
喷火龙8号42 分钟前
MSC中的Model层:数据模型与数据访问层设计
后端·架构
好奇心笔记1 小时前
ai写代码随机拉大的,所以我准备给AI出一个设计规范
前端·javascript
江城开朗的豌豆1 小时前
Vue状态管理进阶:数据到底是怎么"跑"的?
前端·javascript·vue.js
用户21411832636021 小时前
dify案例分享-Dify v1.6.0 重磅升级:双向 MCP 协议引爆 AI 生态互联革命
前端
程序员海军1 小时前
AI领域又新增协议: AG-UI
前端·openai·agent
我想说一句1 小时前
React待办事项开发记:Hook魔法与组件间的悄悄话
前端·javascript·前端框架