手把手教你配置React18调试环境
最近在优化React代码的过程中,发现对React底层逻辑不是很了解,就导致优化过程中没有明确的优化方向,做了很多的无用功。经过一番思考,我决定花费一些时间来进行React源码的学习。
在React源码学习之前,需要先配置一下调试环境,以保证学习的过程中可以进行源码调试。出于恐惧新事物的惯性,上来就是一通百度。一番搜索之后,我发现网上有很多的关于React源码调试环境配置的资料,但是基本上都是React18版本之前的。本以为相差不多,可以hold住,但是配置的过程中才发现React18的源码跟之前的版本的源码有些地方差异很大,这就导致有些报错没有解决方案。所以,我最终就决定自己进行配置,并写下这篇记录希望可以给后续的小伙伴带来帮助。
废话不多说,开撸。
React 源码版本:18.2.0
准备工作
- 
首先,通过 Create React APP创建一个用于调试的React项目;
- 
其次,执行 npm run eject命令,将react项目的配置暴露出来,后续环境配置过程中,我们需要修改webbpack配置;
- 
接下来,通过clone或者下载React的源代码,放置到项目的 src/react 文件夹下。React项目的GitHub地址:github.com/facebook/re… ; 
- 
最后,通过 npm run start命令启动项目,这个时候就可以根据报错进行配置了。
环境配置
依赖配置
我们想要本地调试代码的话,肯定是要调试源代码的,所以我们就需要修改一下webpack配置,将react相关的包依赖指向我们刚刚准备好的 src/react 文件中的依赖。
进入 config/webpack.config.js 文件中,在 resolve.alias 中新增如下配置:
    'react': path.resolve(__dirname, '../src/react/packages/react'),
    'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),
    'react-dom-bindings': path.resolve(__dirname, '../src/react/packages/react-dom-bindings'),
    'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'),
    'shared': path.resolve(__dirname, '../src/react/packages/shared'),
    'scheduler': path.resolve(__dirname, '../src/react/packages/scheduler'),
进入 config/env.js 文件中,在 stringified 变量中新增如下属性:
    __DEV__: true,
    __PROFILE__: true,
    __UMD__: true,
    __EXPERIMENTAL__: true,
    __VARIANT__: false,
解决报错
- 通过报错信息,我们可以看出是:scheduler中没有导出 unstable_yieldValue 和 unstable_setDisableYieldValue模块

解决方案:
进入 packages/scheduler/index.js 文件中,我们发现导出的模块中只导出了 export * from './src/forks/Scheduler';,确实没有导出这两个模块。所以,我们新增如下代码:
    export { unstable_yieldValue, unstable_setDisableYieldValue } from './src/forks/SchedulerMock';
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED属性不存在

解决办法:
我们进入packages/shared/ReactSharedInternals.js文件中,发现源代码中使用了React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,我们做出如下调整:
    // 移除
    - import React from 'react';
    - 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.

解决方案:
进入packages/react-reconciler/src/ReactFiberConfig.js文件中,发现这个报错就是通过throw new Error抛出的,我们做出如下调整:
    // 移除
    - throw new Error('This module must be shimmed by a specific renderer.');
    
    // 新增
    + export * from './forks/ReactFiberHostConfig.dom';
- 通过报错信息我们看出:ReactDOM 和 React模块没有通过default导出

我们进入 packages/react 和 packages/react-dom 下的index.js文件发现确实只是通过export导出了,没有到通过export default导出依赖。我们进入index.js文件,做出如下调整:
    // 移除
    - import React from 'react';
    - import ReactDOM from 'react-dom';
    
    // 新增
    + import * as React from 'react';
    + import * as ReactDOM from 'react-dom';
配置完成
调整完这些之后,我们的代码已经可以跑起来,接下来就是进行源代码的调试了。

转载自:https://juejin.cn/post/7248531609389416506




