引子:react开源很久了,使用它也有5年的时间了,从最开始用的还是0.13.1版本吧,到现在的16.12,版本经过了历次迭代,也变得越来越优秀了,一直没有学习过它的源码,深感惭愧。这次也趁着这次机会吧,一边读一边写,先从react开始,然后是react-dom、react-server、react插件(ReactEventsTap、ReactEventsSwipe、ReactEventsSwipe…) 等等吧,写成一个系列的文章,希望我能写的完,哈哈哈哈😂~
ps:文中若有写的不对的地方,欢迎大家指出来
一、代码
直接GitHub上拉代码吧~https://github.com/facebook/react,我拉的时候react版本是16.12.0,文章也是基于这个版本。
在真正的开始之前吧,先说一下我个人理解的学习过程,我把它分为三个阶段:基础学习、应用实践、原理研究。所谓基础学习是通过其官方文档,学习他的入门、使用方法、API等等;应用实践是指真正使用它去做一些东西,这个过程很重要,通过这个阶段才能了解我们所学的东西能转换成什么样的生产力,也有助于我们的逐步深入;最后一个过程是原理研究,也就是所谓的实现方式的研究,只有经过了这最后一个步骤,才能在我们的个人介绍里写上“精通xxx”了吧😄(个人意见~)
二、项目解析
1、首先,让我们看一下项目的目录解析~
├── build 构建后的输出目录
│ ├── dist react相关
│ ├── facebook-www 插件相关
│ └── react-native react-native相关
├── fixtures React 开发的测试用例
│ ├── art
│ ├── attribute-behavior
│ ├── concurrent
│ ├── devtools
│ ├── dom
│ ├── eslint
│ ├── expiration
│ ├── fiber-debugger
│ ├── fiber-triangle
│ ├── fizz-ssr-browser
│ ├── flight
│ ├── flight-browser
│ ├── packaging
│ ├── scheduler
│ ├── ssr
│ └── tracing
├── packages 源码目录
│ ├── babel-plugin-react-jsx 该软件包旨在最终替代当前的@babel/plugin-transform-react-jsx,将JSX转换从目标React.createElement(type, props, children)更改为React.jsx(types, props, key)
│ ├── create-subscription 在组件里订阅额外数据的工具
│ ├── dom-event-testing-library dom事件测试库
│ ├── eslint-plugin-react-hooks eslint插件钩子
│ ├── jest-mock-scheduler
│ ├── jest-react
│ ├── legacy-events 事件系统
│ ├── react react核心包
│ ├── react-art 矢量图形库
│ ├── react-cache 为 React 应用提供缓存
│ ├── react-debug-tools
│ ├── react-devtools
│ ├── react-devtools-core
│ ├── react-devtools-extensions
│ ├── react-devtools-inline
│ ├── react-devtools-shared
│ ├── react-devtools-shell
│ ├── react-dom DOM 渲染相关
│ ├── react-flight
│ ├── react-flight-dom-webpack
│ ├── react-interactions
│ ├── react-is React 元素类型相关
│ ├── react-native-renderer react-native 渲染相关
│ ├── react-noop-renderer Fiber 测试相关
│ ├── react-reconciler React 调制器
│ ├── react-refresh
│ ├── react-server 服务端渲染
│ ├── react-test-renderer
│ ├── scheduler 调度:异步渲染等
│ ├── shared 通用代码
│ └── use-subscription
└── scripts 公共的babel、eslintflow和release等相关的文件
├── babel
├── bench
├── circleci
├── error-codes
├── eslint
├── eslint-rules
├── flow
├── git
├── jest
├── perf-counters
├── prettier
├── print-warnings
├── release
├── rollup
├── shared
├── tasks
└── yarn
我们主要解析的就是packages下的相关包了。
2、源码构建
这个我们看一下package.json文件里的代码:
{
…
“devDependencies”: {
…
},
…
“scripts”: {
“build”: “node ./scripts/rollup/build.js”,// 构建命令
…
}
}
打包的文件都在./scripts/rollup下了,build文件有740行,是构建所有项目的命令,核心代码如下~
启动打包的方法就是这句了:createBundle(bundle, bundleType)。
打包的项目配置,全部在bundles.js中了
构建的过程会循环包配置文件的配置构建出不同用途的包,依次确定文件名称、打包入口文件、fb文件名称替换、确认依赖包、输出包等过程。那么我们看下createBundle方法里的构建的入口的JS文件地址:
沿着bundle.entry我们发现它的值为react(在scripts/rollup/bundles.js中),require.resolve用于查询文件的完整绝对路径,也就说react对应的真实入口路径是~/work/react/packages/react/index.js(前两级为项目目录),由此不难看出所有源码都在packages中。
3、react入口文件
根据第二步的构建过程我们可以发现,真正的react入口文件为:…/packages/react/src/React.js
三、react源码文件
React.js文件内容如下~
通过这个文件也可以看的出来,其实React相关部分主要就是定义了React对象,他的属性有组件、元素、自元素、上下文、懒加载方法、ref、memo、React Hooks、ReactElementValidator等,至于他们的实现其实主要是在react-dom中,那么我们要解析React的话就从React各个部分的使用方法介绍(着重)以及他们的定义(源码查看)这两个方面来进行吧。
四、小结
本篇文章首先了解了整个项目的结构目录,然后通过查看整个项目的构建文件,研究其构建方式,找到了真正的源码文件入口,也正是开启了react部分的源码的解析系列文章,先预告一下下一篇文章react源码解析–React组件。
欢迎收藏+转发~
ps:再次请求大家如果发现有错误,请帮忙指正~
牛,赞就完事了,