前言
最近想看看react的源码,但是怎么去调试react源码一直困扰着我,今天就来解决这个问题
官网推荐方法
官网推荐的方式是将react打包成了js文件,但是我想要在真实源码中操作,查看官网方式。
Webpack alias
这个方式是通过alias(别名)的方式,将react,react-dom等库的源码指向指定的库中,但是在实际操作的时候遇到了很多报错,我们一点点的来解决。
- 创建react项目
这里为了方便采用create-react-app,也可以自己进行搭建。
npx create-react-app react-code
cd react-code
- 下载react源码
// 这次我们将存放目录放在项目文件里的 src 目录下
cd src
// 我们下载的是带有 v18.2.0 tag 的版本
git clone --branch v18.2.0 https://github.com/facebook/react.git
- 更改webpack的配置
这里因为是脚手架生成的,所以需要命令把webpack配置暴露出来npm run eject - 修改alias
//原配置
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 || {}),
},
//修改后的配置
alias:{
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')
}
修改后运行项目 npm start
5. 报错 修改React和React-Dom的导入
执行完上面的操作后,控制台还剩下5个错误
//src/index
//修改前
import React from 'react';
import ReactDOM from 'react-dom/client';
//修改后
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
- 报错 修改scheduler
// react-app/src/react/packages/react-reconciler/src/Scheduler.js
// 在开头引入 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;
- 报错 关闭eslint
/webpack.config.js
//修改前
const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true';
修改后
const disableESLintPlugin = true
8.修改环境变量
React 的源码里有直接使用
__DEV__等环境变量,我们直接替换掉,修改 config/env.js
// react-app/config/env.js
// 修改前
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};
//修改后
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
__DEV__: true,
__EXPERIMENTAL__: true,
__PROFILE__: true,
};
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
首先找到了报错文件
/src/react/packages/shared/ReactSharedInternals.js
更改如下
// 修改前
const ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// 修改后
import ReactSharedInternals from 'react/src/ReactSharedInternals'
- This module must be shimmed by a specific renderer
打开报错的文件
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";
- 这个时候就可以进行调试了,当修改源码时,页面也会发生相应的变化,vscode调试自行搜索方案吧。