Skip to content

Commit e601994

Browse files
committed
chore(config): update config to load react source
1 parent 9b73461 commit e601994

File tree

7 files changed

+214
-45
lines changed

7 files changed

+214
-45
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
npm-debug.log*
2222
yarn-debug.log*
2323
yarn-error.log*
24-
react
24+
src/react

README.md

Lines changed: 161 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,193 @@
1-
# Getting Started with Create React App
1+
# 调试 React 源码的框架
22

3-
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
3+
我们使用 [create-react-app](https://create-react-app.dev) 脚手架来调试 React 源码。
44

5-
## Available Scripts
5+
## 1. 初始化项目并弹出配置
66

7-
In the project directory, you can run:
7+
首先创建一个项目:
88

9-
### `yarn start`
9+
```shell
10+
$ npx create-react-app debug-react
11+
```
1012

11-
Runs the app in the development mode.\
12-
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13+
我们需要修改很多 webpack 相关的配置,这里把配置弹出来,修改起来更方便一些。
1314

14-
The page will reload when you make changes.\
15-
You may also see any lint errors in the console.
15+
```shell
16+
yarn eject
17+
```
1618

17-
### `yarn test`
19+
## 2. 引入 React 源码
1820

19-
Launches the test runner in the interactive watch mode.\
20-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21+
建议从官方仓库 [facebook/react](https://github.com/facebook/react) fork 一份到自己的名下,这样修改起来还方便一些。如我自己 fork 出来的仓库地址:[wenzi0github/react](https://github.com/wenzi0github/react)
2122

22-
### `yarn build`
23+
在 src 目录中引入 react 源码,大概结构如下:
2324

24-
Builds the app for production to the `build` folder.\
25-
It correctly bundles React in production mode and optimizes the build for the best performance.
25+
```shell
26+
src
27+
react # react源码
28+
App.js
29+
index.js
30+
```
2631

27-
The build is minified and the filenames include the hashes.\
28-
Your app is ready to be deployed!
32+
进入到 react 源码的目录,安装 react 所需要的 npm 包:
2933

30-
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
34+
```shell
35+
$ npm i
3136

32-
### `yarn eject`
37+
# or
3338

34-
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
39+
$ yarn install
40+
```
3541

36-
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
42+
我这里把 debug-react 和 fork 出来的 react 源码放到了两个 Git 仓库中,因此需要在在 debug-react 项目的`.gitignore`文件中,将 src/react 添加到忽略目录中。若您希望都放在一个 Git 仓库中,则可以不修改这里。
3743

38-
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
44+
## 3. 修改 React 中的相关代码
3945

40-
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
46+
react 源码在项目中无法直接使用,这里需要稍微修改下。
4147

42-
## Learn More
48+
### 3.1 eslint 的修改
4349

44-
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
50+
`.eslintrc.js`中,
4551

46-
To learn React, check out the [React documentation](https://reactjs.org/).
52+
1. 把 extends: ['fbjs', 'prettier'] 的数组设置为空;
53+
2. plugins 中的 react 注释掉;
54+
3. rules 中的`no-unused-vars`设置为 OFF;
55+
4. rules 中的`react-internal/no-production-logging` 设置为 OFF;
4756

48-
### Code Splitting
57+
具体如下:
4958

50-
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
59+
```javascript
60+
// 我们忽略其他未修改的属性
61+
module.exports = {
62+
extends: [], // ['fbjs', 'prettier'], debug-react中修改
63+
plugins: [
64+
'jest',
65+
'no-for-of-loops',
66+
'no-function-declare-after-return',
67+
'react',
68+
// 'react', // debug-react中修改
69+
'react-internal',
70+
],
71+
rules: {
72+
'no-unused-vars': OFF, // [ERROR, {args: 'none'}], debug-react中修改
73+
'react-internal/no-production-logging': OFF, // ERROR, debug-react中修改
74+
},
75+
};
76+
```
5177

52-
### Analyzing the Bundle Size
78+
后续在调试的过程,若还有其他 eslint 方面的报错,可以在这个文件里将其对应的规则关闭掉,然后重启即可。
5379

54-
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
80+
### 3.2 源码的修改
5581

56-
### Making a Progressive Web App
82+
#### 3.2.1 packages/scheduler/index.js
5783

58-
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
84+
新增如下代码:
5985

60-
### Advanced Configuration
86+
```javascript
87+
// debug-react调试仓库中添加
88+
export {
89+
unstable_flushAllWithoutAsserting,
90+
unstable_flushNumberOfYields,
91+
unstable_flushExpired,
92+
unstable_clearYields,
93+
unstable_flushUntilNextPaint,
94+
unstable_flushAll,
95+
unstable_yieldValue,
96+
unstable_advanceTime,
97+
unstable_setDisableYieldValue,
98+
} from './src/forks/SchedulerMock';
99+
```
61100

62-
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
101+
#### 3.2.2 packages/react-reconciler/src/ReactFiberHostConfig.js
63102

64-
### Deployment
103+
注释掉 throw error 的代码,并新增 export 的代码:
65104

66-
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
105+
```javascript
106+
// throw new Error('This module must be shimmed by a specific renderer.'); // debug-react中备份
107+
export * from './forks/ReactFiberHostConfig.dom'; // debug-react中修改
108+
```
67109

68-
### `yarn build` fails to minify
110+
#### 3.2.3 packages/shared/ReactSharedInternals.js
69111

70-
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
112+
注释掉 import 和 const 声明的代码,重新进行 import 引入:
113+
114+
```javascript
115+
// import * as React from 'react';
116+
117+
// const ReactSharedInternals =
118+
// React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
119+
120+
import ReactSharedInternals from '../react/src/ReactSharedInternals'; // debug-react中修改
121+
122+
export default ReactSharedInternals;
123+
```
124+
125+
#### 3.2.4 packages/react/index.js
126+
127+
设置默认导出,源码中只有 export 的方式,若外部直接使用,需要用`* as React`这种格式导出成全局变量。React 源码中也有解释:
128+
129+
```javascript
130+
// Export all exports so that they're available in tests.
131+
// We can't use export * from in Flow for some reason.
132+
```
133+
134+
在 Flow 语法中,我们无法用 `export *` 的这种方式来导出所有方法。
135+
136+
因此这里我们单独添加一个默认导出。
137+
138+
```javascript
139+
// 在文件的最底部
140+
141+
// debug-react项目中新增
142+
import * as React from './src/React';
143+
export default React;
144+
// debug-react项目中新增结束
145+
```
146+
147+
#### 3.2.5 packages/react-dom/client.js
148+
149+
同上面的 react 原因,这里我们修改下 ReactDOM:
150+
151+
```javascript
152+
// 在文件的最底部
153+
154+
// debug-react项目中新增
155+
const ReactDOM = { createRoot, hydrateRoot };
156+
export default ReactDOM;
157+
// debug-react项目中新增结束
158+
```
159+
160+
## 4. debug-react 的修改
161+
162+
react 源码中有不少的全局变量,如`__DEV__`等,这里我们需要在`config/env.js`中添加上,否则会提示找不到这个全局变量。
163+
164+
注意,我们回到了最外层的 debug-react 项目了,是修改的用`yarn eject`弹出的配置。我们在变量 stringified 中添加下述变量:
165+
166+
```javascript
167+
// config/env.js
168+
169+
const stringified = {
170+
'process.env': Object.keys(raw).reduce((env, key) => {
171+
env[key] = JSON.stringify(raw[key]);
172+
return env;
173+
}, {}),
174+
175+
// 新增全局变量
176+
__DEV__: true,
177+
__PROFILE__: true,
178+
__UMD__: true,
179+
__EXPERIMENTAL__: true,
180+
__VARIANT__: false,
181+
// 新增全局变量结束
182+
};
183+
```
184+
185+
## 5. 总结
186+
187+
到这里我们基本上就可以改造完毕了,启动项目就可以运行起来。
188+
189+
```shell
190+
$ npm start
191+
```
192+
193+
我们需要在 react 源码中调试或者输出一些 log 时,就可以直接修改了。

config/env.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ function getClientEnvironment(publicUrl) {
9696
env[key] = JSON.stringify(raw[key]);
9797
return env;
9898
}, {}),
99+
100+
// 新增全局变量
101+
__DEV__: true,
102+
__PROFILE__: true,
103+
__UMD__: true,
104+
__EXPERIMENTAL__: true,
105+
__VARIANT__: false,
106+
// 新增全局变量结束
99107
};
100108

101109
return { raw, stringified };

config/webpack.config.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,26 @@ module.exports = function (webpackEnv) {
319319
'scheduler/tracing': 'scheduler/tracing-profiling',
320320
}),
321321
...(modules.webpackAliases || {}),
322+
react: path.resolve(__dirname, "../src/react/packages/react"),
323+
"react-dom": path.resolve(__dirname, "../src/react/packages/react-dom"),
324+
shared: path.resolve(__dirname, "../src/react/packages/shared"),
325+
"react-reconciler": path.resolve(
326+
__dirname,
327+
"../src/react/packages/react-reconciler"
328+
),
329+
scheduler: path.resolve(__dirname, "../src/react/packages/scheduler"),
330+
"react-devtools-scheduling-profiler": path.resolve(
331+
__dirname,
332+
"../src/react/packages/react-devtools-scheduling-profiler"
333+
),
334+
"react-devtools-shared": path.resolve(
335+
__dirname,
336+
"../src/react/packages/react-devtools-shared"
337+
),
338+
"react-devtools-timeline": path.resolve(
339+
__dirname,
340+
"../src/react/packages/react-devtools-timeline"
341+
),
322342
},
323343
plugins: [
324344
// Prevents users from importing files from outside of src/ (or node_modules/).

prettier.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
printWidth: 120,
3+
singleQuote: true,
4+
trailingComma: 'all',
5+
bracketSpacing: true,
6+
jsxBracketSameLine: false,
7+
tabWidth: 2,
8+
semi: true,
9+
arrowParens: 'avoid',
10+
};

src/App.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
import logo from './logo.svg';
22
import './App.css';
3+
import { useEffect } from 'react';
4+
5+
const Count = () => {
6+
useEffect(() => {
7+
console.log('<Count />', Date.now());
8+
}, []);
9+
10+
return (<p>123</p>);
11+
};
312

413
function App() {
14+
useEffect(() => {
15+
console.log('<App />', Date.now());
16+
}, []);
17+
518
return (
619
<div className="App">
720
<header className="App-header">
21+
<Count />
822
<img src={logo} className="App-logo" alt="logo" />
923
<p>
1024
Edit <code>src/App.js</code> and save to reload.

src/index.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@ import React from 'react';
22
import ReactDOM from 'react-dom/client';
33
import './index.css';
44
import App from './App';
5-
import reportWebVitals from './reportWebVitals';
65

76
const root = ReactDOM.createRoot(document.getElementById('root'));
87
root.render(
98
<React.StrictMode>
109
<App />
1110
</React.StrictMode>
1211
);
13-
14-
// If you want to start measuring performance in your app, pass a function
15-
// to log results (for example: reportWebVitals(console.log))
16-
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17-
reportWebVitals();

0 commit comments

Comments
 (0)