Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何正确debug 源码react #1

Open
dravenww opened this issue Feb 8, 2021 · 0 comments
Open

如何正确debug 源码react #1

dravenww opened this issue Feb 8, 2021 · 0 comments
Assignees
Labels

Comments

@dravenww
Copy link
Owner

dravenww commented Feb 8, 2021

网上找了好多debug react的文章,在17上都不好使;在其他前辈们的基础上,进行了自己的尝试,记录下来,算是个开头,使用的是yarn不是npm哈。

  • 安装create-react-app
  • 创建react项目:create-react-app study-react
  • 进入到项目目录,并暴露webpack等配置文件:cd study-react && yarn eject
  • 执行yarn start,确保现在的项目是可以run起来的,结果TMD报错:
     Cannot find module '@babel/plugin-syntax-jsx'
    
  • 没关系,我们安装依赖:yarn add -D @babel/plugin-syntax-jsx
  • 重新执行yarn start,这次跑起来了,打开浏览器输入:http://localhost:3000/,可以看到如下界面:
  • 接下来我们需要把对应的react等依赖,指向源码了,没有源码,我们clone源码,
  • 进入到src目录,执行:git submodule add [email protected]:facebook/react.git,然后切换分支:cd react && git checkout tags/v17.0.0 -b v17.0.0
  • 接下来,我们就得改引用了,也就是webpack的alias配置,进入到项目目录,直接把原先的alias配置全部替换成下面的:
    // @file study-react/config/webpack.config.js
    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'),
      'scheduler': path.resolve(__dirname, "../src/react/packages/scheduler"),
    },
    
  • 重新执行yarn start,编译报错:
    ./src/react/packages/react-reconciler/src/ReactFiberWorkLoop.new.js
    Attempted import error: 'afterActiveInstanceBlur' is not exported from './ReactFiberHostConfig'.
    
  • 我们进入到ReactFiberHostConfig文件,修改下导出:
    // @file src/react/packages/react-reconciler/src/ReactFiberHostConfig.js
    // 当前文件下其他内容全部注释掉即可,没用
    export * from './forks/ReactFiberHostConfig.dom'
    
  • 此时编译会继续报错:
    ./src/index.js
    Attempted import error: 'react' does not contain a default export (imported as 'React').
    
  • 是react引用的问题,我们进到/src/index文件,把对react和react-dom的引用改成下面样子:
    import * as React from 'react';
    import * as ReactDOM from 'react-dom';
    
  • 接下来会继续报编译的错:
    ./src/react/packages/react-reconciler/src/ReactFiberWorkLoop.old.js
    Attempted import error: 'unstable_flushAllWithoutAsserting' is not exported from 'scheduler' (imported as 'Scheduler').
    
  • 我们找到unstable_flushAllWithoutAsserting的声明是在SchedulerHostConfig.mock.js里面,所以我们在scheduler增加以下导出,挺多的,别漏了:
    // @file src/react/packages/scheduler/src/Scheduler.js
    export * from './src/SchedulerHostConfig.js';
    
    // @file 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';
    
    
  • 接下来还是会报错如下,可以看到是eslint的问题:
    Failed to load config "fbjs" to extend from.
    Referenced from: /Users/wuhongjie/mywork/study-react/src/react/.eslintrc.js
    
  • 我们接下来把eslint给去掉,在webpack的配置文件里面,把ESLintPlugin从代码里面注释掉。重新执行yarn start;
  • 这时候,编译已经不报错了,打开浏览器可以看到:
  • 从上面可以得知什么呢?PROFILEEXPERIMENTAL 属于变量替换的问题,我们继续改webpack的配置:
    // @file config/env.js
    const stringified = {
      'process.env': Object.keys(raw).reduce((env, key) => {
        return env;
      }, {}),
      "__DEV__": true,
      "__PROFILE__": true,
      "__UMD__": true,
      "__EXPERIMENTAL__": true
    };
    
  • 本以为接下来就ok了,重新执行yarn start后,发现还是报错
    Error: Internal React error: invariant() is meant to be replaced at compile time. There is no runtime version.
    
  • 上面报错函数invariant报错,现在我们去处理invariant函数:
    // @file src/react/packages/shared/invariant.js
    export default function invariant(condition, format, a, b, c, d, e, f) {
      return false; // 加上这个,啥也不管直接返回false
      throw new Error(
        'Internal React error: invariant() is meant to be replaced at compile ' +
          'time. There is no runtime version.',
      );
    }
    
  • 接下来,重新执行yarn start,看浏览器:

    yeah,成功了!!!
@dravenww dravenww self-assigned this Feb 8, 2021
@dravenww dravenww added the react label Feb 8, 2021
@dravenww dravenww reopened this Mar 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant