react 调试环境搭建

脚手架创建项目

npx create-react-app react-source-analysis
bash

弹射脚手架内部配置

npm run eject
bash

克隆官方源码

git clone https://github.com/facebook/react.git src/react
bash

链接本地源码

// config/webpack.config.js

module.exports = {
  // 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-native': 'react-native-web',
    'react': path.resolve(__dirname, '../src/react/packages/react'),
    'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),
    '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'),
    'shared': path.resolve(__dirname, '../src/react/packages/shared')
  }
}
js

修改 Scheduler.js

// src/react/packages/scheduler/index.js

export {
  unstable_yieldValue,
  unstable_setDisableYieldValue,
} from "./src/forks/SchedulerMock"
js

修改 ReactSharedInternals.js

src/react/packages/shared/ReactSharedInternals.js

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

- 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;
diff

修改 ReactFiberHostConfig.js

src/react/packages/react-reconciler/src/ReactFiberHostConfig.js

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

/* eslint-disable react-internal/prod-error-codes */

// We expect that our Rollup, Jest, and Flow configurations
// always shim this module with the corresponding host config
// (either provided by a renderer, or a generic shim for npm).
//
// We should never resolve to this file, but it exists to make
// sure that if we *do* accidentally break the configuration,
// the failure isn't silent.

- throw new Error('This module must be shimmed by a specific renderer.');

+ export * from './forks//ReactFiberHostConfig.dom'
diff

修改环境变量

config/env.js

const stringified = {
  'process.env': Object.keys(raw).reduce((env, key) => {
    env[key] = JSON.stringify(raw[key])
    return env
  }, {}),
  __DEV__: true,
+ SharedArrayBuffer: true,
+ spyOnDev: true,
+ spyOnDevAndProd: true,
+ spyOnProd: true,
+ __PROFILE__: true,
+ __UMD__: true,
+ __EXPERIMENTAL__: true,
+ __VARIANT__: true,
+ gate: true,
+ trustedTypes: true
}
diff

关闭 ESLint 扩展

src/react/.eslintrc.js

module.exports = {
- extends: ['fbjs', 'prettier']
+ // extends: ['fbjs', 'prettier']
}
diff

新建 .eslintrc.json

// src/.eslintrc.json

{
  "extends": "react-app",
  "globals": {
    "SharedArrayBuffer": true,
    "spyOnDev": true,
    "spyOnDevAndProd": true,
    "spyOnProd": true,
    "__PROFILE__": true,
    "__UMD__": true,
    "__EXPERIMENTAL__": true,
    "__VARIANT__": true,
    "gate": true,
    "trustedTypes": true
  }
}
js

工作区配置,解决 flow 报错

{
  "folders": [
    {
      "path": "react-source-analysis"
    }
  ],
  "settings": {
    "javascript.validate.enable": false
  }
}
json

修改入口文件

src/index.js

- import React from 'react'
- import ReactDOM from 'react-dom/client'
+ import * as React from 'react'
+ import * as ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import reportWebVitals from './reportWebVitals'
diff

删除 eslintConfig 配置

-  "eslintConfig": {
-    "extends": [
-      "react-app",
-      "react-app/jest"
-    ]
-  }
diff

重新安装 npm 包

cd src/react && pnpm i --ignore-scripts
bash
pnpm i
bash

此时启动项目,就可以正常调试 react 源码了。

pnpm run start
bash

debug.png