这应该是第五次开始学习react源码了,前四次开始之后就直接入坟了。。。好的react源码的分析资料太少了。。。还是得自己慢慢探索,希望这次能一步到胃。


源码概述

参考1描述了react源码主要结构:

  1. package/react(React Core)

React core only includes the APIs necessary to define components

  1. package/react-dom(renderers)

Renderers manage how a React tree turns into the underlying platform calls

  1. packages/react-reconciler

    1. declarative rendering
    2. custom components
    3. state
    4. lifecycle methods
    5. refs
  2. packages/legacy-events

Event system

这次计划围绕上面四个方面来探索。


本地学习环境构建

使用版本:16.13.1。

参考2这篇文章很好诶,为啥几乎没有点赞的。。。由于使用的版本和文章中的不同,所以这里详细列下:

  1. 通过create-react-app创建,执行npm run eject暴露出配置文件
  2. 将react源码文件完整拷到上面项目的src目录下
  3. 更改路由解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
resolve:{

...,

alias: {

'react': path.resolve(__dirname, '../src/react/packages/react'),

'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),

'legacy-events': path.resolve(__dirname, '../src/react/packages/legacy-events'),

'shared': path.resolve(__dirname, '../src/react/packages/shared'),

'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'),

},

}
  1. 在wenpack中配置alias之后,需要在/src/react/packages/react'/src/react/packages/react-dom加入对React和ReactDOM的默认导出

  2. 处理flow 检测报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 安装忽略flow检测的插件
npm install @babel/plugin-transform-flow-strip-types -D
// 插件配置
{
test: /\.(js|mjs|jsx|ts|tsx)$/,

include: paths.appSrc,

loader: require.resolve('babel-loader'),

options: {

customize: require.resolve(

'babel-preset-react-app/webpack-overrides'

),

plugins: [

...,

[require.resolve('@babel/plugin-transform-flow-strip-types')]

],
}
  1. 处理全局变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 在/config/env.js中加入

    "__DEV__": false,

    "__PROFILE__": true,

    "__UMD__": true,
    "__EXPERIMENTAL__": true,
    "__VARIANT__": true,
  2. invariant() 函数报错

改为任何时候都直接返回

1
2
3
4
5
6
7
8
9
10
11
export default function invariant(condition, format, a, b, c, d, e, f) {

return;

throw new Error(

'Internal React error: invariant() is meant to be replaced at compile ' +

'time. There is no runtime version.',
);
}
  1. 处理HostConfig配置错误
1
2
3
// 在src/react/packages/react-reconciler/src/ReactFiberHostConfig.js中添加下面的代码

export * from './forks/ReactFiberHostConfig.dom';

参考资料

  1. https://reactjs.org/docs/codebase-overview.html
  2. https://juejin.im/post/5e6e33a3e51d4526ed66cc30