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