### 前言 如果不想麻烦,可以直接在[我的git地址][1]中克隆项目至本地,使用`npm i`安装依赖包,然后`npm run start`启动即可。大 TODO:大白话讲React原理目录: ### 创建 React17 项目 #### 先使用官方脚手架`create-react-app`创建项目 ``` npx create-react-app learn-react-source-code ``` #### 降级 React 版本 我们需要把 React 版本从 18 降到 17 。 ``` "@testing-library/react": "^12.1.5", "react": "^17.0.2", "react-dom": "^17.0.2", ``` ![构建2.jpg][2] #### 修改src/index.js ``` import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; const root = document.getElementById("root"); ReactDOM.render( , root ); ``` ![构建3.jpg][3] #### 尝试运行项目 **删除**根目录下`package-lock.json`,重新安装依赖 `npm i` ,最后 `npm run start`。 此时应该能成功运行项目了,但是目前开发者工具`sources`面板里文件还是打包后的react代码。 为了调试源码,我们还需要做以下步骤 ### 创建带源码的项目 #### 在 src 目录下,克隆 React17 源码 ``` cd src git clone https://github.com/facebook/react.git -b 17.0.2 ``` #### 根目录下,释放 webpack 配置 ``` npm run eject or yarn eject ``` 因为此时 `webpack` 配置全部集成在`react-script`中,我们需要将他释放开来,让我们自己配置 `webpack` 。 命令执行完毕后在新增的 `config` 文件夹下可以看到 `webpack` 的配置文件: ![构建8.jpg][4] #### 根目录下,配置 webpack 使其引用源码 往`config/webpack.config.js` 添加 `alias` ``` // ./config/webpack.config.js ... alias: { ... ...(modules.webpackAliases || {}), + 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" ), + scheduler: path.resolve(__dirname, "../src/react/packages/scheduler"), }, ``` ![构建5.jpg][5] #### 关闭 EsLint ``` // ./config/webpack.config.js ... const disableESLintPlugin = true; ``` ![构建4.jpg][6] #### `config/env.js`添加环境变量 ``` // ./config/env.js ... // Stringify all values so we can feed into webpack DefinePlugin const stringified = { + __DEV__: true, + __PROFILE__: true, + __UMD__: true, + __EXPERIMENTAL__: true, "process.env": Object.keys(raw).reduce((env, key) => { env[key] = JSON.stringify(raw[key]); return env; }, {}), }; ``` ![构建6.jpg][7] #### 修改index.js中 react 和 react-dom 的引入 ``` import * as React from "react"; import * as ReactDOM from "react-dom"; ``` ![构建7.jpg][8] #### 修改报错文件 可以直接[参考此次Commit][9] 如果此时尝试运行项目,webpack会告诉你有 300 多个错误,不要怕,我们马上解决。 `webpack compiled with 336 errors` ##### 1. ./src/react/packages/scheduler/index.js ``` // 添加 export { unstable_flushAllWithoutAsserting, unstable_flushNumberOfYields, unstable_flushExpired, unstable_clearYields, unstable_flushUntilNextPaint, unstable_flushAll, unstable_yieldValue, unstable_advanceTime } from './src/SchedulerHostConfig.js'; ``` ![构建9.jpg][10] ##### 2. ./src/react/packages/shared/invariant.js ``` // 添加 if (condition) { return; } ``` ![构建10.jpg][11] ##### 3. ./src/react/packages/react-reconciler/src/RectFiberHostConfig.js ``` // 注释文件并在最后导出 export * from './forks/ReactFiberHostConfig.dom'; ``` ![构建11.jpg][12] ##### 4. ./src/react/packages/shared/RectSharedInternals.js ``` // 注释文件并添加导入 import ReactSharedInternals from '../react/src/ReactSharedInternals' ``` ![构建12.jpg][13] ##### 5. ./src/react/packages/scheduler/src/SchedulerFeatureFlags.js ``` // 修改 export const enableProfiling = true; ``` ![构建13.jpg][14] ##### 6. ./src/react/packages/scheduler/src/SchedulerHostConfig.js ``` // 注释文件并添加 export { unstable_flushAllWithoutAsserting, unstable_flushNumberOfYields, unstable_flushExpired, unstable_clearYields, unstable_flushUntilNextPaint, unstable_flushAll, unstable_yieldValue, unstable_advanceTime } from './forks/SchedulerHostConfig.mock.js'; export { requestHostCallback, requestHostTimeout, cancelHostTimeout, shouldYieldToHost, getCurrentTime, forceFrameRate, requestPaint } from './forks/SchedulerHostConfig.default.js'; ``` ![构建14.jpg][15] ### 运行项目 此时使用`npm run start`就可以正常运行项目了,通过`debugger`或者`console.log`我们就可以开始调试源码啦。 比如 ![构建1.jpg][16] [1]: https://github.com/232295311/learn-react-source-code [2]: http://120.25.166.245/usr/uploads/2024/03/3108046133.jpg [3]: http://120.25.166.245/usr/uploads/2024/03/2342834140.jpg [4]: http://120.25.166.245/usr/uploads/2024/03/1752848700.jpg [5]: http://120.25.166.245/usr/uploads/2024/03/2043372383.jpg [6]: http://120.25.166.245/usr/uploads/2024/03/3085103012.jpg [7]: http://120.25.166.245/usr/uploads/2024/03/631557534.jpg [8]: http://120.25.166.245/usr/uploads/2024/03/1656241588.jpg [9]: https://github.com/232295311/learn-react-source-code/commit/c968ffd285bd02e45bbfc708ba85279c1590c581 [10]: http://120.25.166.245/usr/uploads/2024/03/387793252.jpg [11]: http://120.25.166.245/usr/uploads/2024/03/3662571732.jpg [12]: http://120.25.166.245/usr/uploads/2024/03/1142517594.jpg [13]: http://120.25.166.245/usr/uploads/2024/03/2628396643.jpg [14]: http://120.25.166.245/usr/uploads/2024/03/2433840008.jpg [15]: http://120.25.166.245/usr/uploads/2024/03/2242156174.jpg [16]: http://120.25.166.245/usr/uploads/2024/03/2318368381.jpg 最后修改:2024 年 03 月 14 日 01 : 17 PM © 著作权归作者所有 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
作者以非凡的视角解读平凡,让文字焕发出别样的光彩。
独特的构思和新颖的观点,让这篇文章在众多作品中脱颖而出。
?总结与建议类?
你的文章让我心情愉悦,真是太棒了! http://www.55baobei.com/Xf4xeGaDfS.html
你的文章让我心情愉悦,真是太棒了! http://www.55baobei.com/a1SUly80Eb.html
你的文章让我感受到了生活的美好,谢谢! https://www.yonboz.com/video/40709.html