|
1 |
| -# Getting Started with Create React App |
| 1 | +# 调试 React 源码的框架 |
2 | 2 |
|
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 源码。 |
4 | 4 |
|
5 |
| -## Available Scripts |
| 5 | +## 1. 初始化项目并弹出配置 |
6 | 6 |
|
7 |
| -In the project directory, you can run: |
| 7 | +首先创建一个项目: |
8 | 8 |
|
9 |
| -### `yarn start` |
| 9 | +```shell |
| 10 | +$ npx create-react-app debug-react |
| 11 | +``` |
10 | 12 |
|
11 |
| -Runs the app in the development mode.\ |
12 |
| -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. |
| 13 | +我们需要修改很多 webpack 相关的配置,这里把配置弹出来,修改起来更方便一些。 |
13 | 14 |
|
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 | +``` |
16 | 18 |
|
17 |
| -### `yarn test` |
| 19 | +## 2. 引入 React 源码 |
18 | 20 |
|
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)。 |
21 | 22 |
|
22 |
| -### `yarn build` |
| 23 | +在 src 目录中引入 react 源码,大概结构如下: |
23 | 24 |
|
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 | +``` |
26 | 31 |
|
27 |
| -The build is minified and the filenames include the hashes.\ |
28 |
| -Your app is ready to be deployed! |
| 32 | +进入到 react 源码的目录,安装 react 所需要的 npm 包: |
29 | 33 |
|
30 |
| -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. |
| 34 | +```shell |
| 35 | +$ npm i |
31 | 36 |
|
32 |
| -### `yarn eject` |
| 37 | +# or |
33 | 38 |
|
34 |
| -**Note: this is a one-way operation. Once you `eject`, you can't go back!** |
| 39 | +$ yarn install |
| 40 | +``` |
35 | 41 |
|
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 仓库中,则可以不修改这里。 |
37 | 43 |
|
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 中的相关代码 |
39 | 45 |
|
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 源码在项目中无法直接使用,这里需要稍微修改下。 |
41 | 47 |
|
42 |
| -## Learn More |
| 48 | +### 3.1 eslint 的修改 |
43 | 49 |
|
44 |
| -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). |
| 50 | +在`.eslintrc.js`中, |
45 | 51 |
|
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; |
47 | 56 |
|
48 |
| -### Code Splitting |
| 57 | +具体如下: |
49 | 58 |
|
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 | +``` |
51 | 77 |
|
52 |
| -### Analyzing the Bundle Size |
| 78 | +后续在调试的过程,若还有其他 eslint 方面的报错,可以在这个文件里将其对应的规则关闭掉,然后重启即可。 |
53 | 79 |
|
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 源码的修改 |
55 | 81 |
|
56 |
| -### Making a Progressive Web App |
| 82 | +#### 3.2.1 packages/scheduler/index.js |
57 | 83 |
|
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 | +新增如下代码: |
59 | 85 |
|
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 | +``` |
61 | 100 |
|
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 |
63 | 102 |
|
64 |
| -### Deployment |
| 103 | +注释掉 throw error 的代码,并新增 export 的代码: |
65 | 104 |
|
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 | +``` |
67 | 109 |
|
68 |
| -### `yarn build` fails to minify |
| 110 | +#### 3.2.3 packages/shared/ReactSharedInternals.js |
69 | 111 |
|
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 时,就可以直接修改了。 |
0 commit comments