Description
其实从Fork仓库到现在,断断续续看了两个月的React源码。这里写下看源码的感受、心得。
首先说一下为什么拖了两个月才开始写总结:
最近工作比较忙,没有比较整块的时间来看源码
要准备专升本的考试,所以重心转移到学习那块去
React是一个社区比较活跃的框架,意味着社区很多人都贡献了代码,代码风格比起vue可能比较杂
里面很多公用变量,加上函数调用栈无比的深,容易看着看着就找不到北
这次是整个过程看下来,目的主要是了解整一个框架的运作,而不是针对某个功能点,所以比较吃力
绝不是因为新来了前端妹纸,导致分心了 (可恶
阅读准备
这里先附上有调试信息以及部分可能有误的注释的react仓库,基于react16.4.1的。
fork 仓库
首先很重要的一点就是,最好最好,不要直接下载React仓库,而是先Fork到自己的仓库,再clone到本地
为什么呢?
因为我们在阅读代码的时候,避免不了自己写注释,改一些变量让他跑向我们需要的分支。你如果是直接下载的话,自己修改的代码既不能提交到远程,也无法和别人共享。我这次就是吃了这个亏,虽然说可以改远程仓库地址push到自己的Github,但是就觉得很奇怪,所以是重新fork之后把修改的文件copy过去.....
找到入口文件
这里可以参考之前看 create-react-app
的方法,由目录结构与package.json
去找。
React项目是多包共用一套构建工具,包都放在 packages/*
, 可以看到有 react
、react-dom
、events
等文件夹,基本上可以靠文件夹的名字猜到放的是什么模块的东西。
写个demo,找到断点调试
对于这种比较大型的框架,相比起干巴巴的看源码,写个demo顺着断点看代码更容易理解一些。
可以写个简单一点的,然后想看什么部分就再自己添加对于的代码进去。比如想看事件系统,那你的demo就必须要有一些事件函数,如onClick
等,然后在入口的地方打断点慢慢步进看。
进入开发模式
React仓库比较蛋疼的是我没找到一些本地开发的方法,可能只是我没发现。
因为平时项目一般会留一个类型npm run dev
之类的命令直接开本地服务,提供热更新、自动编译之类的功能。但是在 package.json
的scripts
里面我没找到对应的命令,知道的小伙伴可以say一下...
所以我的方法比较笨,是直接在 packages/*
找到一些想看的文件,然后写 debugger
或者 console.log
,然后再修改一下 react的构建脚本,这样构建出来的包就是带有我们想要的调试信息。然后demo页引进这个调试信息的包慢慢看断点。
我这里看 package.json
发现只提供了 build
命令,于是我加了一些参数,然后再去修改build脚本./scripts/rollup/build.js
"build": "npm run version-check && node ./scripts/rollup/build.js",
"jsonz-build": "yarn build core,dom --type=UMD --jsonz"
加了个判断,让他只编译想要看的核心文件,以及只编译一种UMD类型。
这个方法虽然没有那么高大上,但是在 15年的mbp 上,直接用react仓库的npm run build
跑一次需要花 450s,而改进之后,一次只需要 17s,足足快了27倍!。配合vscode的脚本运行快捷键可以比较快速看到效果。
阅读中
不纠结小变量、小函数
在看源码的过程中,很忌讳一个函数一个函数死扣着一些变量和方法不放。因为这样很难跳出那些方法,容易看着看着就被绕进去,忘了你要看的是什么。其实看源码很多是了解他的运行原理,有问题的时候可以快速定位,排查问题。再高一点就是抽象他的框架思想,为后面造轮子或造工作做准备。比如京东的Taro
或司徒的anu
都多多少少得了解react的源码、机制。
分阶段
分阶段是指将整个过程分成几个阶段,这样方便归纳理解,可以参考我的一篇流水文,虽然分的不是很好...
多记录与打日志
对于了解整个运行机制来说,打日志是很有必要的,因为很多情况你看断点一下子就过去了。要想回到刚才的位置可能又得重新跑一遍,打日志可以帮助你回顾刚才执行到的一些方法。
关于记录,其实我看的时候会把一些关键的信息记下来,方便反复查阅,比如任务的优先级、fiber的类型、effect的类型等
多利用思维导图以及流程图理解
人类对图标的理解能力远比干巴巴的文字强,所以多用思维导图和流程图来帮助自己理清一个逻辑。
结语
这次看完源码虽然没有真的一整个库的所有细节都很理解,但是对整一个流程还是有所了解。
在工作上遇到一些意料之外的执行结果也比以前淡定很多,按着思路想了一下基本就知道问题出在哪个环节,比以前容易定位到问题。
也通过源码知道了一些东西,比如新的生命周期函数(捂脸逃...居然是通过源码才知道的),还有就是一些关于React的很优秀的网址。
其实一直拖着不肯写的一个很大的原因是没有达到一个比较好的境界,对于fiber的异步调度这块不是很能理解,也很难抽象到整一个框架的思想层面。
特别是看完总结出来的也只是很枯燥的流水代码形式,没办法讲的有趣让别人能留下一些印象,这一块让我很受挫。
附上看源码过程中翻到的比较好的网站,前人栽树后人乘凉。
官方React fiber 介绍 地址
React Changelog 更新日志 可以帮助我们快速了解到React的一些 feature地址
React 官方Blog 其实很多文章都是翻译官网blog的,基本上属于第一手的资料地址
《React源码解析》系列 虽然是基于15版本的,但是像一些看源码时的问题还是很值得参考地址
如何阅读大型前端开源项目的源码地址
完全理解React Fiber 几乎是目前为止看到写的最通熟易懂的,再一次捂脸地址
司徒正妹儿写的React16.2的fiber架构 地址
fiber系统的完成情况,每天同步fiber的进展 很有趣的网站 地址
不错的React事件机制 地址
React事件系统讲解 地址
React动画一直是个比较尴尬的问题,这里做了比较系统的总结 地址