# react源码调试环境 **Repository Path**: machinist_wq/react-source-code ## Basic Information - **Project Name**: react源码调试环境 - **Description**: react18源码的调试环境搭建 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: https://gitee.com/machinist_wq/react-source-code - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-28 - **Last Updated**: 2022-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: React ## README ## 创建一个react项目 ``` npx create-react-app debug-react cd debug-react ``` ## 运行eject,创建config目录,暴露webpack配置 ``` npm run eject ``` 执行完这个命令,会把项目中的webpack暴露出来,并且修改package中的script 执行之前的项目目录 ![执行之前的项目目录](readme-image/Wechat1.png) 执行之后的项目目录 ![执行之后的项目目录](readme-image/Wechat2.png) **并没有readme-image这个文件夹 这是我用来存放图片的 ** 执行之前的script ![执行之前的script](readme-image/WeChat3.png) 执行之后的script ![执行之后的script](readme-image/Wechat4.png) ## 克隆react代码 可以选择直接克隆github的源码,也可以使用压缩包解压的放方式,均可。 将拉下来的代码防止src目录下的react目录下 ![](readme-image/Wechat5.png) ## config/webpack.config.js修改alias指向,指向下载到本地的react代码 ``` alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ // *把之前的指向全部注释掉 // 'react-native': 'react-native-web', // // Allows for better profiling with ReactDevTools // ...(**isEnvProductionProfile** && { // 'react-dom$': 'react-dom/profiling', // 'scheduler/tracing': 'scheduler/tracing-profiling', // }), // ...(modules.webpackAliases || {}), // *修改为下面这段指向 react: path.join(paths.appSrc, 'react/packages/react'), 'react-dom': path.join(paths.appSrc, 'react/packages/react-dom'), shared: path.join(paths.appSrc, 'react/packages/shared'), 'react-reconciler': path.join( paths.appSrc, 'react/packages/react-reconciler' ), 'legacy-events': path.join( paths.appSrc, 'react/packages/legacy-events' ), scheduler: path.join(paths.appSrc, 'react/packages/scheduler'), } ``` ## 修改react-app/src/index.js入口文件的引入方式 本地代码没有和react包默认输出不一样,我们需要修改本地代码的引入方式 ``` // * 原代码 import React from 'react'; import ReactDOM from 'react-dom/client'; // * 修改后代码 import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; ``` ## 为了方便调试,选择关闭EsLint 在config/webpack.config.js全局搜索disableESLintPlugin配置 ``` // * 将这段代码注释 // const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true'; // * 将disableESLintPlugin改为true const disableESLintPlugin = true; ``` ## 启动项目看是否可以正常启动 ``` npm run start ``` ## 解决错误 ### 官方测试需要修改的mock文件 ![](readme-image/Wechat6.png) 找到react-app/src/react/packages/react-reconciler/src/Scheduler.js文件并添加mock文件 ``` // * 在文件开头引入SchedulerMock import * as SchedulerMock from 'scheduler/src/forks/SchedulerMock'; // * 然后将后面的 // export const unstable_yieldValue = Scheduler.unstable_yieldValue; // export const unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue; // * 替换为 export const unstable_yieldValue = SchedulerMock.unstable_yieldValue; export const unstable_setDisableYieldValue = SchedulerMock.unstable_setDisableYieldValue; ``` 报错是没有了但是页面依旧没正常显示,打开控制台我们看到了接下来的问题。 ### 环境变量缺失问题 ![](readme-image/Wechat7.png) 这是环境变量配置的问题 我们打开/config/env.js,搜索stringified字段 ``` const stringified = { 'process.env': Object.keys(raw).reduce((env, key) => { env[key] = JSON.stringify(raw[key]); return env; }, {}), // * 加上 __EXPERIMENTAL__: true, }; ``` 重启项目即可 后续有两个同样的问题,就不过多赘述了,同样的解决方案 ``` const stringified = { 'process.env': Object.keys(raw).reduce((env, key) => { env[key] = JSON.stringify(raw[key]); return env; }, {}), // * 加上 __EXPERIMENTAL__: true, __PROFILE__: true, __DEV__: true, }; ``` 修改以后一定要记得重启项目,不然不会生效! ### 解决__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED问题 ![](readme-image/Wechat8.png) 修改src/react/packages/shared/ReactSharedInternals.js ``` // * 注释这段 // import * as React from 'react'; // const ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // * 添加这段 import ReactSharedInternals from '../react/src/ReactSharedInternals' export default ReactSharedInternals; ``` ### This module must be shimmed by a specific renderer ![](readme-image/Wechat9.png) 修改src/react/packages/react-reconciler/src/ReactFiberHostConfig.js ``` // * 注释这段 // throw new Error('This module must be shimmed by a specific renderer.'); // * 加入这段 export * from './forks/ReactFiberHostConfig.dom'; ``` ## 项目正常启动 ![](readme-image/Wechat10.png) ## 开始debugger ![](readme-image/Wechat11.png) **一个react源码的调试环境就愉快的搭建好了,开始探索的旅程吧!**