文章目录
-
-
- 本地调试react源码步骤
-
- 1. 生成react项目
- 2. yarn run eject 暴露出webpack配置
- 3.清理src目录
- 4.clone react源码至src目录下
- 5.修改webpack.config.js添加alias配置
- 6.修改ReactFiberHostConfig文件
- 7.修改react引用方式
- 8.关闭ESlint对fbjs,prettier插件的扩展
- 9.安装eslint-plugin-no-for-of-loops插件
- 10.修改scheduler/index.js文件
- 11.解决react-internal错误
- 12.修复react/jsx-dev-runtime报错
- 13.设置DefinePlugin插件
- 14.修改invariant.js
-
工欲善其事,必先利其器。
在学习raect源码时,如果能够在浏览器中单步调试,势必会加深理解。其实可以借助webpack的resolve.alias插件将react等指向本地的目录,这样就不会使用node_modules中的react包。
从而可以在本地调试react源码。
本地调试react源码步骤
1. 生成react项目
可以直接基于react cra cli生成项目,也可以自己基于react,webpack搭建环境,具体可以参考https://github.com/bozhouyongqi/react-redux-demo项目。下述主要针对使用cra的项目。
2. yarn run eject 暴露出webpack配置
这一步没有没什么,可以看到会生成config目录,里面包括webpack的配置文件和一些环境定义。但是很不幸,运行yarn run start会编译失败。出现下述错误。
Failed to compile.
./src/index.js
Error: [BABEL] /xxx/debug-react-new/src/index.js: Cannot find module '@babel/plugin-syntax-jsx' (While processing: "xxx/debug-react-new/node_modules/babel-preset-react-app/index.js")
意思是缺少@babel/plugin-syntax-jsx这个模块,那直接安装就行。
yarn add @babel/plugin-syntax-jsx -D
之后再运行,就可以顺利启动项目了。
Compiled successfully!
You can now view debug-react-new in the browser.
Local: http://localhost:3000
On Your Network: http://192.168.0.103:3000
Note that the development build is not optimized.
To create a production build, use yarn build.
3.清理src目录
删除测试以及其他文件,只保留App等业务组件。并去除相关引用。
4.clone react源码至src目录下
这里使用git submodule命令引入react源码作为子模块,以方便后续代码单独管理。
进入src目录,执行 git submodule add git@github.com:facebook/react.git。
克隆之后,就可以在src/react中正常切换分支,而不影响主工程。我这里使用v16.13.1版本,因此可以切换至具体的tag.
git checkout tags/v16.13.1 -b v16.13.1
5.修改webpack.config.js添加alias配置
注释掉原先的alias配置,添加新的,将react等指向本地
alias: {
'react': path.resolve(__dirname, '../src/react/packages/react'),
'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),
'shared': path.resolve(__dirname, '../src/react/packages/shared'),
'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'),
"legacy-events": path.resolve(__dirname, "../src/react/packages/legacy-events"),
// 'react-event