|
| 1 | +最新的请查看 React 源码学习指南.md |
| 2 | + |
| 3 | +源码文件指引地址:https://www.processon.com/view/link/60b206c2e0b34d3841931a88 |
| 4 | + |
| 5 | +##说明 |
| 6 | +本项目用于调试源码,即修改配置使得项目中引用的 react 包来自 src/react,使得我们可以在 src/react 下 debug 和打 log 调试。 |
| 7 | + |
| 8 | +##使用步骤 |
| 9 | + |
| 10 | +1. 在根目录下安装: yarn add |
| 11 | +2. 下载 react 包到 src 下,并按照下面的修改配置步骤修改 react 中的文件。 |
| 12 | +3. 在根目录下启动: yarn start |
| 13 | + |
| 14 | +### 修改配置 |
| 15 | + |
| 16 | +废弃~ 晚点更新 |
| 17 | + |
| 18 | +### 修改 react 包 |
| 19 | + |
| 20 | +**最新的 react 包只需要修改下面的 1、2、3、6、7。(2021.7.27)** |
| 21 | + |
| 22 | +如果想要自己重新 clone react,有以下一些文件需要更改: |
| 23 | + |
| 24 | +1. /src/react/packages/react-reconciler/src/ReactFiberHostConfig.js |
| 25 | + |
| 26 | +```jsx |
| 27 | +// import invariant from 'shared/invariant'; |
| 28 | +//invariant(false, 'This module must be shimmed by a specific renderer.'); //sy |
| 29 | +// sy |
| 30 | +export * from "./forks/ReactFiberHostConfig.dom"; |
| 31 | +``` |
| 32 | + |
| 33 | +2. /src/react/packages/shared/invariant.js |
| 34 | + |
| 35 | +```jsx |
| 36 | +export default function invariant(condition, format, a, b, c, d, e, f) { |
| 37 | + if (condition) return; // sy 加上这个 |
| 38 | + |
| 39 | + throw new Error( |
| 40 | + "Internal React error: invariant() is meant to be replaced at compile " + |
| 41 | + "time. There is no runtime version." |
| 42 | + ); |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +3. /src/react/packages/shared/ReactSharedInternals.js |
| 47 | + |
| 48 | +```jsx |
| 49 | +// import React from 'react'; |
| 50 | +// const ReactSharedInternals = |
| 51 | +// React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; |
| 52 | + |
| 53 | +// sy |
| 54 | +import ReactSharedInternals from "../react/src/ReactSharedInternals"; |
| 55 | +``` |
| 56 | + |
| 57 | +4. /src/react/packages/scheduler/index.js |
| 58 | + |
| 59 | + ```jsx |
| 60 | + "use strict"; |
| 61 | + |
| 62 | + export * from "./src/Scheduler"; |
| 63 | + // sy 添加以下 |
| 64 | + export { |
| 65 | + unstable_flushAllWithoutAsserting, |
| 66 | + unstable_flushNumberOfYields, |
| 67 | + unstable_flushExpired, |
| 68 | + unstable_clearYields, |
| 69 | + unstable_flushUntilNextPaint, |
| 70 | + unstable_flushAll, |
| 71 | + unstable_yieldValue, |
| 72 | + unstable_advanceTime, |
| 73 | + unstable_setDisableYieldValue, |
| 74 | + } from "./src/forks/SchedulerMock"; |
| 75 | + ``` |
| 76 | + |
| 77 | +5. react/.eslintrc.js |
| 78 | + |
| 79 | +1)搜索 extends: ['fbjs', 'prettier'],把这个数组置空。 |
| 80 | + |
| 81 | +2)搜索 no-function-declare-after-return 和 react-internal,把相关的代码行全部注释掉。 |
| 82 | + |
| 83 | +3)搜索 eol-last,把` 'eol-last': ERROR,`的 ERROR 改为 OFF |
| 84 | + |
| 85 | +4)搜索 quotes,把 quotes 和 jsx-quotes 的值也修改为 OFF |
| 86 | + |
| 87 | +5)搜索 no-unused-vars,把 no-unused-vars 的值也改为 OFF |
| 88 | + |
| 89 | +我修改后的文件如下: |
| 90 | + |
| 91 | +```js |
| 92 | +"use strict"; |
| 93 | + |
| 94 | +const { |
| 95 | + es5Paths, |
| 96 | + esNextPaths, |
| 97 | +} = require("./scripts/shared/pathsByLanguageVersion"); |
| 98 | + |
| 99 | +const restrictedGlobals = require("confusing-browser-globals"); |
| 100 | + |
| 101 | +const OFF = 0; |
| 102 | +const ERROR = 2; |
| 103 | + |
| 104 | +module.exports = { |
| 105 | + extends: [], // sy['fbjs', 'prettier'], |
| 106 | + |
| 107 | + // Stop ESLint from looking for a configuration file in parent folders |
| 108 | + root: true, |
| 109 | + |
| 110 | + plugins: [ |
| 111 | + "jest", |
| 112 | + "no-for-of-loops", |
| 113 | + // 'no-function-declare-after-return', |
| 114 | + "react", |
| 115 | + // 'react-internal', |
| 116 | + ], |
| 117 | + |
| 118 | + parser: "babel-eslint", |
| 119 | + parserOptions: { |
| 120 | + ecmaVersion: 8, |
| 121 | + sourceType: "script", |
| 122 | + ecmaFeatures: { |
| 123 | + experimentalObjectRestSpread: true, |
| 124 | + }, |
| 125 | + }, |
| 126 | + |
| 127 | + // We're stricter than the default config, mostly. We'll override a few rules |
| 128 | + // and then enable some React specific ones. |
| 129 | + rules: { |
| 130 | + "accessor-pairs": OFF, |
| 131 | + "brace-style": [ERROR, "1tbs"], |
| 132 | + "consistent-return": OFF, |
| 133 | + "dot-location": [ERROR, "property"], |
| 134 | + // We use console['error']() as a signal to not transform it: |
| 135 | + "dot-notation": [ERROR, { allowPattern: "^(error|warn)$" }], |
| 136 | + "eol-last": OFF, //ERROR, |
| 137 | + eqeqeq: [ERROR, "allow-null"], |
| 138 | + indent: OFF, |
| 139 | + "jsx-quotes": OFF, // [ERROR, 'prefer-double'], |
| 140 | + "keyword-spacing": [ERROR, { after: true, before: true }], |
| 141 | + "no-bitwise": OFF, |
| 142 | + "no-console": OFF, |
| 143 | + "no-inner-declarations": [ERROR, "functions"], |
| 144 | + "no-multi-spaces": ERROR, |
| 145 | + "no-restricted-globals": [ERROR].concat(restrictedGlobals), |
| 146 | + "no-restricted-syntax": [ERROR, "WithStatement"], |
| 147 | + "no-shadow": ERROR, |
| 148 | + "no-unused-expressions": ERROR, |
| 149 | + "no-unused-vars": OFF, //[ERROR, {args: 'none'}], |
| 150 | + "no-use-before-define": OFF, |
| 151 | + "no-useless-concat": OFF, |
| 152 | + quotes: OFF, // [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true}], |
| 153 | + "space-before-blocks": ERROR, |
| 154 | + "space-before-function-paren": OFF, |
| 155 | + "valid-typeof": [ERROR, { requireStringLiterals: true }], |
| 156 | + // Flow fails with with non-string literal keys |
| 157 | + "no-useless-computed-key": OFF, |
| 158 | + |
| 159 | + // We apply these settings to files that should run on Node. |
| 160 | + // They can't use JSX or ES6 modules, and must be in strict mode. |
| 161 | + // They can, however, use other ES6 features. |
| 162 | + // (Note these rules are overridden later for source files.) |
| 163 | + "no-var": ERROR, |
| 164 | + strict: ERROR, |
| 165 | + |
| 166 | + // Enforced by Prettier |
| 167 | + // TODO: Prettier doesn't handle long strings or long comments. Not a big |
| 168 | + // deal. But I turned it off because loading the plugin causes some obscure |
| 169 | + // syntax error and it didn't seem worth investigating. |
| 170 | + "max-len": OFF, |
| 171 | + // Prettier forces semicolons in a few places |
| 172 | + "flowtype/object-type-delimiter": OFF, |
| 173 | + |
| 174 | + // React & JSX |
| 175 | + // Our transforms set this automatically |
| 176 | + "react/jsx-boolean-value": [ERROR, "always"], |
| 177 | + "react/jsx-no-undef": ERROR, |
| 178 | + // We don't care to do this |
| 179 | + "react/jsx-sort-prop-types": OFF, |
| 180 | + "react/jsx-space-before-closing": ERROR, |
| 181 | + "react/jsx-uses-react": ERROR, |
| 182 | + "react/no-is-mounted": OFF, |
| 183 | + // This isn't useful in our test code |
| 184 | + "react/react-in-jsx-scope": ERROR, |
| 185 | + "react/self-closing-comp": ERROR, |
| 186 | + // We don't care to do this |
| 187 | + "react/jsx-wrap-multilines": [ |
| 188 | + ERROR, |
| 189 | + { declaration: false, assignment: false }, |
| 190 | + ], |
| 191 | + |
| 192 | + // Prevent for...of loops because they require a Symbol polyfill. |
| 193 | + // You can disable this rule for code that isn't shipped (e.g. build scripts and tests). |
| 194 | + "no-for-of-loops/no-for-of-loops": ERROR, |
| 195 | + |
| 196 | + // Prevent function declarations after return statements |
| 197 | + // sy |
| 198 | + // 'no-function-declare-after-return/no-function-declare-after-return': ERROR, |
| 199 | + |
| 200 | + // CUSTOM RULES |
| 201 | + // the second argument of warning/invariant should be a literal string |
| 202 | + // sy |
| 203 | + // 'react-internal/no-primitive-constructors': OFF, |
| 204 | + // 'react-internal/no-to-warn-dev-within-to-throw': OFF, |
| 205 | + // 'react-internal/invariant-args': OFF, |
| 206 | + // 'react-internal/warning-args': OFF, |
| 207 | + // 'react-internal/no-production-logging': OFF, |
| 208 | + // 'react-internal/no-cross-fork-imports': OFF, |
| 209 | + // 'react-internal/no-cross-fork-types': OFF, |
| 210 | + // [ |
| 211 | + // ERROR, |
| 212 | + // { |
| 213 | + // old: [], |
| 214 | + // new: [], |
| 215 | + // }, |
| 216 | + // ], |
| 217 | + }, |
| 218 | + |
| 219 | + overrides: [ |
| 220 | + { |
| 221 | + // We apply these settings to files that we ship through npm. |
| 222 | + // They must be ES5. |
| 223 | + files: es5Paths, |
| 224 | + parser: "espree", |
| 225 | + parserOptions: { |
| 226 | + ecmaVersion: 5, |
| 227 | + sourceType: "script", |
| 228 | + }, |
| 229 | + rules: { |
| 230 | + "no-var": OFF, |
| 231 | + strict: ERROR, |
| 232 | + }, |
| 233 | + }, |
| 234 | + { |
| 235 | + // We apply these settings to the source files that get compiled. |
| 236 | + // They can use all features including JSX (but shouldn't use `var`). |
| 237 | + files: esNextPaths, |
| 238 | + parser: "babel-eslint", |
| 239 | + parserOptions: { |
| 240 | + ecmaVersion: 8, |
| 241 | + sourceType: "module", |
| 242 | + }, |
| 243 | + rules: { |
| 244 | + "no-var": ERROR, |
| 245 | + "prefer-const": ERROR, |
| 246 | + strict: OFF, |
| 247 | + }, |
| 248 | + }, |
| 249 | + { |
| 250 | + files: ["**/__tests__/*.js"], |
| 251 | + rules: { |
| 252 | + // https://github.com/jest-community/eslint-plugin-jest |
| 253 | + "jest/no-focused-tests": ERROR, |
| 254 | + "jest/valid-expect": ERROR, |
| 255 | + "jest/valid-expect-in-promise": ERROR, |
| 256 | + }, |
| 257 | + }, |
| 258 | + { |
| 259 | + files: [ |
| 260 | + "**/__tests__/**/*.js", |
| 261 | + "scripts/**/*.js", |
| 262 | + "packages/*/npm/**/*.js", |
| 263 | + "packages/dom-event-testing-library/**/*.js", |
| 264 | + "packages/react-devtools*/**/*.js", |
| 265 | + ], |
| 266 | + rules: { |
| 267 | + // 'react-internal/no-production-logging': OFF, |
| 268 | + // 'react-internal/warning-args': OFF, |
| 269 | + |
| 270 | + // Disable accessibility checks |
| 271 | + "jsx-a11y/aria-role": OFF, |
| 272 | + "jsx-a11y/no-noninteractive-element-interactions": OFF, |
| 273 | + "jsx-a11y/no-static-element-interactions": OFF, |
| 274 | + "jsx-a11y/role-has-required-aria-props": OFF, |
| 275 | + "jsx-a11y/no-noninteractive-tabindex": OFF, |
| 276 | + "jsx-a11y/tabindex-no-positive": OFF, |
| 277 | + }, |
| 278 | + }, |
| 279 | + { |
| 280 | + files: [ |
| 281 | + "scripts/eslint-rules/*.js", |
| 282 | + "packages/eslint-plugin-react-hooks/src/*.js", |
| 283 | + ], |
| 284 | + plugins: ["eslint-plugin"], |
| 285 | + rules: { |
| 286 | + "eslint-plugin/prefer-object-rule": ERROR, |
| 287 | + "eslint-plugin/require-meta-fixable": [ |
| 288 | + ERROR, |
| 289 | + { catchNoFixerButFixableProperty: true }, |
| 290 | + ], |
| 291 | + "eslint-plugin/require-meta-has-suggestions": ERROR, |
| 292 | + }, |
| 293 | + }, |
| 294 | + { |
| 295 | + files: [ |
| 296 | + "packages/react-native-renderer/**/*.js", |
| 297 | + "packages/react-server-native-relay/**/*.js", |
| 298 | + ], |
| 299 | + globals: { |
| 300 | + nativeFabricUIManager: true, |
| 301 | + }, |
| 302 | + }, |
| 303 | + { |
| 304 | + files: ["packages/react-server-dom-webpack/**/*.js"], |
| 305 | + globals: { |
| 306 | + __webpack_chunk_load__: true, |
| 307 | + __webpack_require__: true, |
| 308 | + }, |
| 309 | + }, |
| 310 | + { |
| 311 | + files: ["packages/scheduler/**/*.js"], |
| 312 | + globals: { |
| 313 | + TaskController: true, |
| 314 | + }, |
| 315 | + }, |
| 316 | + ], |
| 317 | + |
| 318 | + globals: { |
| 319 | + spyOnDev: true, |
| 320 | + spyOnDevAndProd: true, |
| 321 | + spyOnProd: true, |
| 322 | + __EXPERIMENTAL__: true, |
| 323 | + __EXTENSION__: true, |
| 324 | + __PROFILE__: true, |
| 325 | + __TEST__: true, |
| 326 | + __UMD__: true, |
| 327 | + __VARIANT__: true, |
| 328 | + gate: true, |
| 329 | + trustedTypes: true, |
| 330 | + }, |
| 331 | +}; |
| 332 | +``` |
| 333 | + |
| 334 | +6. 根据控制台此时的报错,找到报错信息以 react-internal 开头文件,然后搜索 react-internal,把相关注释全部去掉。或者在 react/packages 下暴力全局搜索 react-internal,把包含 react-internal 的注释行全部删掉。当然后者东西比较多,因为全局下有些文件里的 react-internal 并不影响运行,可以不删除的。建议选择前者。 |
0 commit comments