├── .DS_Store
├── .eslintcache
├── .gitignore
├── .yarnrc.yml
├── DebugReact.code-workspace
├── README.md
├── build
├── favicon.ico
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── config
├── .DS_Store
├── env.js
├── getHttpsConfig.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── modules.js
├── paths.js
├── pnpTs.js
├── webpack.config.js
└── webpackDevServer.config.js
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── scripts
├── build.js
├── start.js
└── test.js
├── src
├── .DS_Store
├── RootRouter.jsx
├── components
│ ├── .DS_Store
│ ├── Button.js
│ ├── MySlowList.js
│ ├── Num.js
│ └── User.js
├── index.css
├── index.js
├── pages
│ ├── .DS_Store
│ ├── AboutThisPage.js
│ ├── ActionPage.jsx
│ ├── ClassFunctionComponent.jsx
│ ├── CloneElementPage.js
│ ├── CommentListPage.jsx
│ ├── ContextPage.jsx
│ ├── ContextPage2.jsx
│ ├── DiffPage.jsx
│ ├── ErrorBoundaryPage.js
│ ├── ExamplePage.jsx
│ ├── FunctionComponent.jsx
│ ├── FunctionComponentForceUpdate.js
│ ├── LifeCyclePage.jsx
│ ├── NewHookApi.js
│ ├── OptimizingPage.js
│ ├── PureComponentPage.jsx
│ ├── ReactMemoPage.jsx
│ ├── RefPage.jsx
│ ├── RefPage19.jsx
│ ├── ServerComponentWithoutServer.jsx
│ ├── SetStatePage.jsx
│ ├── SuspensePage.js
│ ├── TransitionPage.js
│ ├── TransitionPage2.js
│ ├── UseActionStatePage.jsx
│ ├── UseCallbackPage.jsx
│ ├── UseDeferredValuePage.js
│ ├── UseFormStatusPage.jsx
│ ├── UseMemoPage.jsx
│ ├── UseOptimisticPage copy.jsx
│ ├── UseOptimisticPage.jsx
│ ├── UseOptimisticPage2.jsx
│ └── UsePage.jsx
├── store
│ ├── createStore.js
│ └── index.js
├── utils.js
└── whichReact.js
├── yarn.lock
└── 那些我回答了800遍的问题.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/DebugReact/b25db1deda39e2cdd176a0ed45bd72d189b62ad4/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | react-/
3 | # react/
4 |
5 | .yarn/*
6 |
7 | src/-react*
8 |
9 | *.zip
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/DebugReact.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": ".",
5 | },
6 | ],
7 | "settings": {
8 | "better-comments.tags": [
9 | {
10 | "tag": "sy-",
11 | "color": "yellow",
12 | "strikethrough": false,
13 | "underline": false,
14 | "backgroundColor": "#000",
15 | "bold": false,
16 | "italic": false,
17 | },
18 | {
19 | "tag": "!",
20 | "color": "#cf40c2",
21 | "strikethrough": false,
22 | "underline": false,
23 | "backgroundColor": "transparent",
24 | "bold": false,
25 | "italic": false,
26 | },
27 | {
28 | "tag": "?",
29 | "color": "#cf6640",
30 | "strikethrough": false,
31 | "underline": false,
32 | "backgroundColor": "transparent",
33 | "bold": false,
34 | "italic": false,
35 | },
36 | {
37 | "tag": "//",
38 | "color": "#474747",
39 | "strikethrough": true,
40 | "underline": false,
41 | "backgroundColor": "transparent",
42 | "bold": false,
43 | "italic": false,
44 | },
45 | {
46 | "tag": "todo",
47 | "color": "#FF8C00",
48 | "strikethrough": false,
49 | "underline": false,
50 | "backgroundColor": "transparent",
51 | "bold": false,
52 | "italic": false,
53 | },
54 | {
55 | "tag": "*",
56 | "color": "green", //"#9c27b0",
57 | "strikethrough": false,
58 | "underline": false,
59 | "backgroundColor": "transparent",
60 | "bold": false,
61 | "italic": false,
62 | },
63 | ],
64 | "editor.cursorWidth": 2,
65 | },
66 | }
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React 源码学习指南
2 |
3 | 1. 本项目属于课程资源,已购买课程学员可以联系我「微信: bubucuo_sy」,获取完整版~
4 |
5 | 2. 更多资源,关注公众号|b站|YouTube:bubucuo
6 |
7 | ## 前言
8 |
9 | 本项目用于调试源码,即修改配置使得项目中引用的 react 包来自 src/react,使得我们可以在 src/react 下 debug 和打 log 调试。
10 |
11 | ## 使用步骤
12 |
13 | 1. 在根目录下安装: yarn add
14 | 2. 下载 react 包到 src 下,并按照下面的修改配置步骤修改 react 中的文件。
15 | 3. 在根目录下启动: yarn start
16 |
17 | # 自己从 github 下载 react 包并修改配置
18 |
19 | 1. /src/react/packages/scheduler/index.js
20 |
21 | ```jsx
22 | "use strict";
23 |
24 | export * from "./src/forks/Scheduler";
25 |
26 | // sy- 添加以下
27 | export {
28 | log,
29 | unstable_flushAllWithoutAsserting,
30 | unstable_flushNumberOfYields,
31 | unstable_flushExpired,
32 | unstable_flushUntilNextPaint,
33 | unstable_flushAll,
34 | unstable_advanceTime,
35 | unstable_setDisableYieldValue,
36 | } from "./src/forks/SchedulerMock";
37 | ```
38 |
39 | 2. /src/react/packages/react-reconciler/src/ReactFiberConfig.js
40 |
41 | ```jsx
42 | // throw new Error('This module must be shimmed by a specific renderer.');
43 |
44 | // sy-
45 | export * from "./forks/ReactFiberConfig.dom";
46 | export { bindToConsole } from "../../react-client/src/ReactClientConsoleConfigBrowser";
47 | ```
48 |
49 | 3. src/react/packages/react-reconciler/src/forks/ReactFiberConfig.dom.js
50 |
51 | ```js
52 | // export * from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
53 | // export * from 'react-client/src/ReactClientConsoleConfigBrowser';
54 | // sy--
55 | export * from "../../../react-dom-bindings/src/client/ReactFiberConfigDOM";
56 | export * from "../../../react-client/src/ReactClientConsoleConfigBrowser";
57 | ```
58 |
59 | 4. /src/react/packages/shared/ReactSharedInternals.js
60 |
61 | ```jsx
62 | // import * as React from 'react';
63 |
64 | // const ReactSharedInternals =
65 | // React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
66 |
67 | // sy
68 | import ReactSharedInternals from "../react/src/ReactSharedInternalsClient";
69 |
70 | export default ReactSharedInternals;
71 | ```
72 |
73 | 5. src/react/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
74 |
75 | ```js
76 | // 在export type ViewTransitionInstance = { 前面增加以下代码
77 | // sy-
78 | type Animatable = any;
79 | type Keyframe = any;
80 | type PropertyIndexedKeyframes = any;
81 | type KeyframeAnimationOptions = any;
82 | type GetAnimationsOptions = any;
83 | type EventListenerOptionsOrUseCapture = any;
84 | type FocusOptions = any;
85 | ```
86 |
87 | 6. src/react/packages/react-reconciler/src/ReactFiberDevToolsHook.js
88 |
89 | ```js
90 | // declare const __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
91 | // sy-
92 | var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
93 | ```
94 |
95 | 7. src/react/.eslintrc.js
96 |
97 | 我修改后的文件如下:
98 |
99 | ```js
100 | 'use strict';
101 |
102 | const {
103 | es5Paths,
104 | esNextPaths,
105 | } = require('./scripts/shared/pathsByLanguageVersion');
106 |
107 | const restrictedGlobals = require('confusing-browser-globals');
108 |
109 | const OFF = 0;
110 | const WARNING = 1;
111 | const ERROR = 2;
112 |
113 | module.exports = {
114 | extends: ['plugin:jest/recommended'],
115 |
116 | // Stop ESLint from looking for a configuration file in parent folders
117 | root: true,
118 |
119 | reportUnusedDisableDirectives: false, //true,
120 |
121 | plugins: [
122 | // 'babel',
123 | 'ft-flow',
124 | 'jest',
125 | 'es',
126 | 'no-for-of-loops',
127 | 'no-function-declare-after-return',
128 | 'react',
129 | 'react-internal',
130 | ],
131 |
132 | parser: 'hermes-eslint',
133 | parserOptions: {
134 | ecmaVersion: 9,
135 | sourceType: 'script',
136 | },
137 |
138 | // We're stricter than the default config, mostly. We'll override a few rules
139 | // and then enable some React specific ones.
140 | rules: {
141 | 'ft-flow/array-style-complex-type': [OFF, 'verbose'],
142 | 'ft-flow/array-style-simple-type': [OFF, 'verbose'], // TODO should be WARNING
143 | 'ft-flow/boolean-style': ERROR,
144 | 'ft-flow/no-dupe-keys': ERROR,
145 | 'ft-flow/no-primitive-constructor-types': ERROR,
146 | 'ft-flow/no-types-missing-file-annotation': OFF, // TODO should be ERROR
147 | 'ft-flow/no-unused-expressions': ERROR,
148 | // 'ft-flow/no-weak-types': WARNING,
149 | // 'ft-flow/require-valid-file-annotation': ERROR,
150 | 'es/no-optional-chaining': ERROR,
151 | 'no-cond-assign': OFF,
152 | 'no-constant-condition': OFF,
153 | 'no-control-regex': OFF,
154 | 'no-debugger': OFF,
155 | 'no-dupe-args': ERROR,
156 | 'no-dupe-keys': ERROR,
157 | 'no-duplicate-case': WARNING,
158 | 'no-empty-character-class': WARNING,
159 | 'no-empty': OFF,
160 | 'no-ex-assign': WARNING,
161 | 'no-extra-boolean-cast': WARNING,
162 | 'no-func-assign': ERROR,
163 | 'no-invalid-regexp': WARNING,
164 | 'no-irregular-whitespace': WARNING,
165 | 'no-negated-in-lhs': ERROR,
166 | 'no-obj-calls': ERROR,
167 | 'no-regex-spaces': WARNING,
168 | 'no-sparse-arrays': ERROR,
169 | 'no-unreachable': ERROR,
170 | 'use-isnan': ERROR,
171 | 'valid-jsdoc': OFF,
172 | 'block-scoped-var': OFF,
173 | complexity: OFF,
174 | 'default-case': OFF,
175 | 'guard-for-in': OFF,
176 | 'no-alert': OFF,
177 | 'no-caller': ERROR,
178 | 'no-case-declarations': OFF,
179 | 'no-div-regex': OFF,
180 | 'no-else-return': OFF,
181 | 'no-empty-pattern': WARNING,
182 | 'no-eq-null': OFF,
183 | 'no-eval': ERROR,
184 | 'no-extend-native': WARNING,
185 | 'no-extra-bind': WARNING,
186 | 'no-fallthrough': WARNING,
187 | 'no-implicit-coercion': OFF,
188 | 'no-implied-eval': ERROR,
189 | 'no-invalid-this': OFF,
190 | 'no-iterator': OFF,
191 | 'no-labels': [ERROR, {allowLoop: true, allowSwitch: true}],
192 | 'no-lone-blocks': WARNING,
193 | 'no-loop-func': OFF,
194 | 'no-magic-numbers': OFF,
195 | 'no-multi-str': ERROR,
196 | 'no-native-reassign': [ERROR, {exceptions: ['Map', 'Set']}],
197 | 'no-new-func': ERROR,
198 | 'no-new': WARNING,
199 | 'no-new-wrappers': WARNING,
200 | 'no-octal-escape': WARNING,
201 | 'no-octal': WARNING,
202 | 'no-param-reassign': OFF,
203 | 'no-process-env': OFF,
204 | 'no-proto': ERROR,
205 | 'no-redeclare': OFF, // TODO should be WARNING?
206 | 'no-return-assign': OFF,
207 | 'no-script-url': ERROR,
208 | 'no-self-compare': WARNING,
209 | 'no-sequences': WARNING,
210 | 'no-throw-literal': ERROR,
211 | 'no-useless-call': WARNING,
212 | 'no-void': OFF,
213 | 'no-warning-comments': OFF,
214 | 'no-with': OFF,
215 | radix: WARNING,
216 | 'vars-on-top': OFF,
217 | yoda: OFF,
218 | 'init-declarations': OFF,
219 | 'no-catch-shadow': ERROR,
220 | 'no-delete-var': ERROR,
221 | 'no-label-var': WARNING,
222 | 'no-shadow-restricted-names': WARNING,
223 | 'no-undef-init': OFF,
224 | 'no-undef': OFF,
225 | 'no-undefined': OFF,
226 | 'callback-return': OFF,
227 | 'global-require': OFF,
228 | 'handle-callback-err': OFF,
229 | 'no-mixed-requires': OFF,
230 | 'no-new-require': OFF,
231 | 'no-path-concat': OFF,
232 | 'no-process-exit': OFF,
233 | 'no-restricted-modules': OFF,
234 | 'no-sync': OFF,
235 | camelcase: [OFF, {properties: 'always'}],
236 | 'consistent-this': [OFF, 'self'],
237 | 'func-names': OFF,
238 | 'func-style': [OFF, 'declaration'],
239 | 'id-length': OFF,
240 | 'id-match': OFF,
241 | 'max-depth': OFF,
242 | 'max-nested-callbacks': OFF,
243 | 'max-params': OFF,
244 | 'max-statements': OFF,
245 | 'new-cap': OFF,
246 | 'newline-after-var': OFF,
247 | 'no-array-constructor': ERROR,
248 | 'no-continue': OFF,
249 | 'no-inline-comments': OFF,
250 | 'no-lonely-if': OFF,
251 | 'no-negated-condition': OFF,
252 | 'no-nested-ternary': OFF,
253 | 'no-new-object': WARNING,
254 | 'no-plusplus': OFF,
255 | 'no-ternary': OFF,
256 | 'no-underscore-dangle': OFF,
257 | 'no-unneeded-ternary': WARNING,
258 | 'one-var': [WARNING, {initialized: 'never'}],
259 | 'operator-assignment': [WARNING, 'always'],
260 | 'require-jsdoc': OFF,
261 | 'sort-vars': OFF,
262 | 'spaced-comment': [
263 | OFF,
264 | 'always',
265 | {exceptions: ['jshint', 'jslint', 'eslint', 'global']},
266 | ],
267 | 'constructor-super': ERROR,
268 | 'no-class-assign': WARNING,
269 | 'no-const-assign': ERROR,
270 | 'no-dupe-class-members': ERROR,
271 | 'no-this-before-super': ERROR,
272 | 'object-shorthand': OFF,
273 | 'prefer-const': OFF,
274 | 'prefer-spread': OFF,
275 | 'prefer-reflect': OFF,
276 | 'prefer-template': OFF,
277 | 'require-yield': OFF,
278 | 'babel/generator-star-spacing': OFF,
279 | 'babel/new-cap': OFF,
280 | 'babel/array-bracket-spacing': OFF,
281 | 'babel/object-curly-spacing': OFF,
282 | 'babel/object-shorthand': OFF,
283 | 'babel/arrow-parens': OFF,
284 | 'babel/no-await-in-loop': OFF,
285 | 'babel/flow-object-type': OFF,
286 | 'react/display-name': OFF,
287 | 'react/forbid-prop-types': OFF,
288 | 'react/jsx-closing-bracket-location': OFF,
289 | 'react/jsx-curly-spacing': OFF,
290 | 'react/jsx-equals-spacing': WARNING,
291 | 'react/jsx-filename-extension': OFF,
292 | 'react/jsx-first-prop-new-line': OFF,
293 | 'react/jsx-handler-names': OFF,
294 | 'react/jsx-indent': OFF,
295 | 'react/jsx-indent-props': OFF,
296 | 'react/jsx-key': OFF,
297 | 'react/jsx-max-props-per-line': OFF,
298 | 'react/jsx-no-bind': OFF,
299 | 'react/jsx-no-duplicate-props': ERROR,
300 | 'react/jsx-no-literals': OFF,
301 | 'react/jsx-no-target-blank': OFF,
302 | 'react/jsx-pascal-case': OFF,
303 | 'react/jsx-sort-props': OFF,
304 | 'react/jsx-uses-vars': OFF,
305 | 'react/no-comment-textnodes': OFF,
306 | 'react/no-danger': OFF,
307 | 'react/no-deprecated': OFF,
308 | 'react/no-did-mount-set-state': OFF,
309 | 'react/no-did-update-set-state': OFF,
310 | 'react/no-direct-mutation-state': OFF,
311 | 'react/no-multi-comp': OFF,
312 | 'react/no-render-return-value': OFF,
313 | 'react/no-set-state': OFF,
314 | 'react/no-string-refs': OFF,
315 | 'react/no-unknown-property': OFF,
316 | 'react/prefer-es6-class': OFF,
317 | 'react/prefer-stateless-function': OFF,
318 | 'react/prop-types': OFF,
319 | 'react/require-extension': OFF,
320 | 'react/require-optimization': OFF,
321 | 'react/require-render-return': OFF,
322 | 'react/sort-comp': OFF,
323 | 'react/sort-prop-types': OFF,
324 |
325 | 'accessor-pairs': OFF,
326 | 'brace-style': [ERROR, '1tbs'],
327 | 'consistent-return': OFF,
328 | 'dot-location': [ERROR, 'property'],
329 | // We use console['error']() as a signal to not transform it:
330 | 'dot-notation': [ERROR, {allowPattern: '^(error|warn)$'}],
331 | 'eol-last': ERROR,
332 | eqeqeq: [ERROR, 'allow-null'],
333 | indent: OFF,
334 | 'jsx-quotes': [ERROR, 'prefer-double'],
335 | 'keyword-spacing': [ERROR, {after: true, before: true}],
336 | 'no-bitwise': OFF,
337 | 'no-console': OFF,
338 | 'no-inner-declarations': [ERROR, 'functions'],
339 | 'no-multi-spaces': ERROR,
340 | 'no-restricted-globals': [ERROR].concat(restrictedGlobals),
341 | 'no-restricted-syntax': [
342 | ERROR,
343 | 'WithStatement',
344 | {
345 | selector: 'MemberExpression[property.name=/^(?:substring|substr)$/]',
346 | message: 'Prefer string.slice() over .substring() and .substr().',
347 | },
348 | ],
349 | 'no-shadow': ERROR,
350 | 'no-unused-vars': OFF, //[ERROR, {args: 'none', ignoreRestSiblings: true}],
351 | 'no-use-before-define': OFF,
352 | 'no-useless-concat': OFF,
353 | quotes: [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true}],
354 | 'space-before-blocks': ERROR,
355 | 'space-before-function-paren': OFF,
356 | 'valid-typeof': [ERROR, {requireStringLiterals: true}],
357 | // Flow fails with non-string literal keys
358 | 'no-useless-computed-key': OFF,
359 |
360 | // We apply these settings to files that should run on Node.
361 | // They can't use JSX or ES6 modules, and must be in strict mode.
362 | // They can, however, use other ES6 features.
363 | // (Note these rules are overridden later for source files.)
364 | 'no-var': ERROR,
365 | strict: ERROR,
366 |
367 | // Enforced by Prettier
368 | // TODO: Prettier doesn't handle long strings or long comments. Not a big
369 | // deal. But I turned it off because loading the plugin causes some obscure
370 | // syntax error and it didn't seem worth investigating.
371 | 'max-len': OFF,
372 |
373 | // React & JSX
374 | // Our transforms set this automatically
375 | 'react/jsx-boolean-value': [ERROR, 'always'],
376 | 'react/jsx-no-undef': OFF, //ERROR,
377 | // We don't care to do this
378 | 'react/jsx-sort-prop-types': OFF,
379 | 'react/jsx-space-before-closing': ERROR,
380 | 'react/jsx-uses-react': ERROR,
381 | 'react/no-is-mounted': OFF,
382 | // This isn't useful in our test code
383 | 'react/react-in-jsx-scope': ERROR,
384 | 'react/self-closing-comp': ERROR,
385 | // We don't care to do this
386 | 'react/jsx-wrap-multilines': [
387 | ERROR,
388 | {declaration: false, assignment: false},
389 | ],
390 |
391 | // Prevent for...of loops because they require a Symbol polyfill.
392 | // You can disable this rule for code that isn't shipped (e.g. build scripts and tests).
393 | 'no-for-of-loops/no-for-of-loops': ERROR,
394 |
395 | // Prevent function declarations after return statements
396 | 'no-function-declare-after-return/no-function-declare-after-return': ERROR,
397 |
398 | // CUSTOM RULES
399 | // the second argument of warning/invariant should be a literal string
400 | 'react-internal/no-primitive-constructors': ERROR,
401 | 'react-internal/safe-string-coercion': [
402 | ERROR,
403 | {isProductionUserAppCode: true},
404 | ],
405 | 'react-internal/warning-args': ERROR,
406 | 'react-internal/no-production-logging': OFF,
407 | },
408 |
409 | overrides: [
410 | {
411 | // By default, anything error message that appears the packages directory
412 | // must have a corresponding error code. The exceptions are defined
413 | // in the next override entry.
414 | files: ['packages/**/*.js'],
415 | rules: {
416 | 'react-internal/prod-error-codes': ERROR,
417 | },
418 | },
419 | {
420 | // These are files where it's OK to have unminified error messages. These
421 | // are environments where bundle size isn't a concern, like tests
422 | // or Node.
423 | files: [
424 | 'packages/react-dom/src/test-utils/**/*.js',
425 | 'packages/react-devtools-shared/**/*.js',
426 | 'packages/react-noop-renderer/**/*.js',
427 | 'packages/react-refresh/**/*.js',
428 | 'packages/react-server-dom-esm/**/*.js',
429 | 'packages/react-server-dom-webpack/**/*.js',
430 | 'packages/react-server-dom-turbopack/**/*.js',
431 | 'packages/react-server-dom-parcel/**/*.js',
432 | 'packages/react-server-dom-fb/**/*.js',
433 | 'packages/react-test-renderer/**/*.js',
434 | 'packages/react-debug-tools/**/*.js',
435 | 'packages/react-devtools-extensions/**/*.js',
436 | 'packages/react-devtools-timeline/**/*.js',
437 | 'packages/react-native-renderer/**/*.js',
438 | 'packages/eslint-plugin-react-hooks/**/*.js',
439 | 'packages/jest-react/**/*.js',
440 | 'packages/internal-test-utils/**/*.js',
441 | 'packages/**/__tests__/*.js',
442 | 'packages/**/npm/*.js',
443 | ],
444 | rules: {
445 | 'react-internal/prod-error-codes': OFF,
446 | },
447 | },
448 | {
449 | // We apply these settings to files that we ship through npm.
450 | // They must be ES5.
451 | files: es5Paths,
452 | parser: 'espree',
453 | parserOptions: {
454 | ecmaVersion: 5,
455 | sourceType: 'script',
456 | },
457 | rules: {
458 | 'no-var': OFF,
459 | strict: ERROR,
460 | },
461 | },
462 | {
463 | // We apply these settings to the source files that get compiled.
464 | // They can use all features including JSX (but shouldn't use `var`).
465 | files: esNextPaths,
466 | parser: 'hermes-eslint',
467 | parserOptions: {
468 | ecmaVersion: 8,
469 | sourceType: 'module',
470 | },
471 | rules: {
472 | 'no-var': OFF,
473 | 'prefer-const': OFF,
474 | strict: OFF,
475 | },
476 | },
477 | {
478 | files: ['**/__tests__/*.js'],
479 | rules: {
480 | // https://github.com/jest-community/eslint-plugin-jest
481 | // Meh, who cares.
482 | 'jest/consistent-test-it': OFF,
483 | // Meh, we have a lot of these, who cares.
484 | 'jest/no-alias-methods': OFF,
485 | // We do conditions based on feature flags.
486 | 'jest/no-conditional-expect': OFF,
487 | // We have our own assertion helpers.
488 | 'jest/expect-expect': OFF,
489 | // Lame rule that fires in itRender helpers or in render methods.
490 | 'jest/no-standalone-expect': OFF,
491 | },
492 | },
493 | {
494 | // Rules specific to test setup helper files.
495 | files: [
496 | '**/setupTests.js',
497 | '**/setupEnv.js',
498 | '**/jest/TestFlags.js',
499 | '**/dom-event-testing-library/testHelpers.js',
500 | '**/utils/ReactDOMServerIntegrationTestUtils.js',
501 | '**/babel/transform-react-version-pragma.js',
502 | '**/babel/transform-test-gate-pragma.js',
503 | ],
504 | rules: {
505 | // Some helpers intentionally focus tests.
506 | 'jest/no-focused-tests': OFF,
507 | // Test fn helpers don't use static text names.
508 | 'jest/valid-title': OFF,
509 | // We have our own assertion helpers.
510 | 'jest/expect-expect': OFF,
511 | // Some helpers intentionally disable tests.
512 | 'jest/no-disabled-tests': OFF,
513 | // Helpers export text function helpers.
514 | 'jest/no-export': OFF,
515 | // The examples in comments trigger false errors.
516 | 'jest/no-commented-out-tests': OFF,
517 | },
518 | },
519 | {
520 | files: ['**/jest/TestFlags.js'],
521 | rules: {
522 | // The examples in comments trigger false errors.
523 | 'jest/no-commented-out-tests': OFF,
524 | },
525 | },
526 | {
527 | files: [
528 | '**/__tests__/**/*.js',
529 | 'scripts/**/*.js',
530 | 'packages/*/npm/**/*.js',
531 | 'packages/dom-event-testing-library/**/*.js',
532 | 'packages/react-devtools*/**/*.js',
533 | 'dangerfile.js',
534 | 'fixtures',
535 | 'packages/react-dom/src/test-utils/*.js',
536 | ],
537 | rules: {
538 | 'es/no-optional-chaining': OFF,
539 | 'react-internal/no-production-logging': OFF,
540 | 'react-internal/warning-args': OFF,
541 | 'react-internal/safe-string-coercion': [
542 | ERROR,
543 | {isProductionUserAppCode: false},
544 | ],
545 | },
546 | },
547 | {
548 | files: ['scripts/eslint-rules/*.js'],
549 | plugins: ['eslint-plugin'],
550 | rules: {
551 | 'eslint-plugin/prefer-object-rule': ERROR,
552 | 'eslint-plugin/require-meta-fixable': [
553 | ERROR,
554 | {catchNoFixerButFixableProperty: true},
555 | ],
556 | 'eslint-plugin/require-meta-has-suggestions': ERROR,
557 | },
558 | },
559 | {
560 | files: ['packages/react-native-renderer/**/*.js'],
561 | globals: {
562 | nativeFabricUIManager: 'readonly',
563 | RN$enableMicrotasksInReact: 'readonly',
564 | },
565 | },
566 | {
567 | files: ['packages/react-server-dom-webpack/**/*.js'],
568 | globals: {
569 | __webpack_chunk_load__: 'readonly',
570 | __webpack_require__: 'readonly',
571 | },
572 | },
573 | {
574 | files: ['packages/react-server-dom-turbopack/**/*.js'],
575 | globals: {
576 | __turbopack_load__: 'readonly',
577 | __turbopack_require__: 'readonly',
578 | },
579 | },
580 | {
581 | files: ['packages/react-server-dom-parcel/**/*.js'],
582 | globals: {
583 | parcelRequire: 'readonly',
584 | },
585 | },
586 | {
587 | files: ['packages/scheduler/**/*.js'],
588 | globals: {
589 | TaskController: 'readonly',
590 | },
591 | },
592 | {
593 | files: [
594 | 'packages/react-devtools-extensions/**/*.js',
595 | 'packages/react-devtools-shared/src/devtools/views/**/*.js',
596 | 'packages/react-devtools-shared/src/hook.js',
597 | 'packages/react-devtools-shared/src/backend/console.js',
598 | 'packages/react-devtools-shared/src/backend/shared/DevToolsComponentStackFrame.js',
599 | 'packages/react-devtools-shared/src/frontend/utils/withPermissionsCheck.js',
600 | ],
601 | globals: {
602 | __IS_CHROME__: 'readonly',
603 | __IS_FIREFOX__: 'readonly',
604 | __IS_EDGE__: 'readonly',
605 | __IS_NATIVE__: 'readonly',
606 | __IS_INTERNAL_VERSION__: 'readonly',
607 | chrome: 'readonly',
608 | },
609 | },
610 | {
611 | files: ['packages/react-devtools-shared/**/*.js'],
612 | globals: {
613 | __IS_INTERNAL_VERSION__: 'readonly',
614 | },
615 | },
616 | {
617 | files: ['packages/eslint-plugin-react-hooks/src/**/*'],
618 | extends: ['plugin:@typescript-eslint/recommended'],
619 | parser: '@typescript-eslint/parser',
620 | plugins: ['@typescript-eslint', 'eslint-plugin'],
621 | rules: {
622 | '@typescript-eslint/no-explicit-any': OFF,
623 | '@typescript-eslint/no-non-null-assertion': OFF,
624 | '@typescript-eslint/array-type': [ERROR, {default: 'generic'}],
625 |
626 | 'es/no-optional-chaining': OFF,
627 |
628 | 'eslint-plugin/prefer-object-rule': ERROR,
629 | 'eslint-plugin/require-meta-fixable': [
630 | ERROR,
631 | {catchNoFixerButFixableProperty: true},
632 | ],
633 | 'eslint-plugin/require-meta-has-suggestions': ERROR,
634 | },
635 | },
636 | ],
637 |
638 | env: {
639 | browser: true,
640 | es6: true,
641 | node: true,
642 | jest: true,
643 | },
644 |
645 | globals: {
646 | $Call: 'readonly',
647 | $ElementType: 'readonly',
648 | $Flow$ModuleRef: 'readonly',
649 | $FlowFixMe: 'readonly',
650 | $Keys: 'readonly',
651 | $NonMaybeType: 'readonly',
652 | $PropertyType: 'readonly',
653 | $ReadOnly: 'readonly',
654 | $ReadOnlyArray: 'readonly',
655 | $ArrayBufferView: 'readonly',
656 | $Shape: 'readonly',
657 | CallSite: 'readonly',
658 | ConsoleTask: 'readonly', // TOOD: Figure out what the official name of this will be.
659 | ReturnType: 'readonly',
660 | AnimationFrameID: 'readonly',
661 | // For Flow type annotation. Only `BigInt` is valid at runtime.
662 | bigint: 'readonly',
663 | BigInt: 'readonly',
664 | BigInt64Array: 'readonly',
665 | BigUint64Array: 'readonly',
666 | Class: 'readonly',
667 | ClientRect: 'readonly',
668 | CopyInspectedElementPath: 'readonly',
669 | DOMHighResTimeStamp: 'readonly',
670 | EventListener: 'readonly',
671 | Iterable: 'readonly',
672 | AsyncIterable: 'readonly',
673 | $AsyncIterable: 'readonly',
674 | $AsyncIterator: 'readonly',
675 | Iterator: 'readonly',
676 | AsyncIterator: 'readonly',
677 | IteratorResult: 'readonly',
678 | JSONValue: 'readonly',
679 | JSResourceReference: 'readonly',
680 | MouseEventHandler: 'readonly',
681 | PropagationPhases: 'readonly',
682 | PropertyDescriptor: 'readonly',
683 | React$AbstractComponent: 'readonly',
684 | React$Component: 'readonly',
685 | React$ComponentType: 'readonly',
686 | React$Config: 'readonly',
687 | React$Context: 'readonly',
688 | React$Element: 'readonly',
689 | React$ElementConfig: 'readonly',
690 | React$ElementProps: 'readonly',
691 | React$ElementRef: 'readonly',
692 | React$ElementType: 'readonly',
693 | React$Key: 'readonly',
694 | React$Node: 'readonly',
695 | React$Portal: 'readonly',
696 | React$Ref: 'readonly',
697 | React$RefSetter: 'readonly',
698 | ReadableStreamController: 'readonly',
699 | ReadableStreamReader: 'readonly',
700 | RequestInfo: 'readonly',
701 | RequestOptions: 'readonly',
702 | StoreAsGlobal: 'readonly',
703 | symbol: 'readonly',
704 | SyntheticEvent: 'readonly',
705 | SyntheticMouseEvent: 'readonly',
706 | Thenable: 'readonly',
707 | TimeoutID: 'readonly',
708 | WheelEventHandler: 'readonly',
709 | FinalizationRegistry: 'readonly',
710 | Omit: 'readonly',
711 | Keyframe: 'readonly',
712 | PropertyIndexedKeyframes: 'readonly',
713 | KeyframeAnimationOptions: 'readonly',
714 | GetAnimationsOptions: 'readonly',
715 | Animatable: 'readonly',
716 | ScrollTimeline: 'readonly',
717 | EventListenerOptionsOrUseCapture: 'readonly',
718 | FocusOptions: 'readonly',
719 |
720 | spyOnDev: 'readonly',
721 | spyOnDevAndProd: 'readonly',
722 | spyOnProd: 'readonly',
723 | __DEV__: 'readonly',
724 | __EXPERIMENTAL__: 'readonly',
725 | __EXTENSION__: 'readonly',
726 | __PROFILE__: 'readonly',
727 | __TEST__: 'readonly',
728 | __VARIANT__: 'readonly',
729 | __unmockReact: 'readonly',
730 | gate: 'readonly',
731 | trustedTypes: 'readonly',
732 | IS_REACT_ACT_ENVIRONMENT: 'readonly',
733 | AsyncLocalStorage: 'readonly',
734 | async_hooks: 'readonly',
735 | globalThis: 'readonly',
736 | },
737 | };
738 | ```
739 |
740 | 8. `yarn start`启动项目,此时可能依然有报错,这时候可以根据控制台此时的错误提示,再酌情修改。
741 |
--------------------------------------------------------------------------------
/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/DebugReact/b25db1deda39e2cdd176a0ed45bd72d189b62ad4/build/favicon.ico
--------------------------------------------------------------------------------
/build/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/DebugReact/b25db1deda39e2cdd176a0ed45bd72d189b62ad4/build/logo192.png
--------------------------------------------------------------------------------
/build/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/DebugReact/b25db1deda39e2cdd176a0ed45bd72d189b62ad4/build/logo512.png
--------------------------------------------------------------------------------
/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/build/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/config/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/DebugReact/b25db1deda39e2cdd176a0ed45bd72d189b62ad4/config/.DS_Store
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const fs = require("fs");
4 | const path = require("path");
5 | const paths = require("./paths");
6 |
7 | // Make sure that including paths.js after env.js will read .env variables.
8 | delete require.cache[require.resolve("./paths")];
9 |
10 | const NODE_ENV = process.env.NODE_ENV;
11 | if (!NODE_ENV) {
12 | throw new Error(
13 | "The NODE_ENV environment variable is required but was not specified."
14 | );
15 | }
16 |
17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
18 | const dotenvFiles = [
19 | `${paths.dotenv}.${NODE_ENV}.local`,
20 | // Don't include `.env.local` for `test` environment
21 | // since normally you expect tests to produce the same
22 | // results for everyone
23 | NODE_ENV !== "test" && `${paths.dotenv}.local`,
24 | `${paths.dotenv}.${NODE_ENV}`,
25 | paths.dotenv,
26 | ].filter(Boolean);
27 |
28 | // Load environment variables from .env* files. Suppress warnings using silent
29 | // if this file is missing. dotenv will never modify any environment variables
30 | // that have already been set. Variable expansion is supported in .env files.
31 | // https://github.com/motdotla/dotenv
32 | // https://github.com/motdotla/dotenv-expand
33 | dotenvFiles.forEach((dotenvFile) => {
34 | if (fs.existsSync(dotenvFile)) {
35 | require("dotenv-expand")(
36 | require("dotenv").config({
37 | path: dotenvFile,
38 | })
39 | );
40 | }
41 | });
42 |
43 | // We support resolving modules according to `NODE_PATH`.
44 | // This lets you use absolute paths in imports inside large monorepos:
45 | // https://github.com/facebook/create-react-app/issues/253.
46 | // It works similar to `NODE_PATH` in Node itself:
47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
49 | // Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
50 | // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
51 | // We also resolve them to make sure all tools using them work consistently.
52 | const appDirectory = fs.realpathSync(process.cwd());
53 | process.env.NODE_PATH = (process.env.NODE_PATH || "")
54 | .split(path.delimiter)
55 | .filter((folder) => folder && !path.isAbsolute(folder))
56 | .map((folder) => path.resolve(appDirectory, folder))
57 | .join(path.delimiter);
58 |
59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
60 | // injected into the application via DefinePlugin in webpack configuration.
61 | const REACT_APP = /^REACT_APP_/i;
62 |
63 | function getClientEnvironment(publicUrl) {
64 | const raw = Object.keys(process.env)
65 | .filter((key) => REACT_APP.test(key))
66 | .reduce(
67 | (env, key) => {
68 | env[key] = process.env[key];
69 | return env;
70 | },
71 | {
72 | // Useful for determining whether we’re running in production mode.
73 | // Most importantly, it switches React into the correct mode.
74 | NODE_ENV: process.env.NODE_ENV || "development",
75 | // Useful for resolving the correct path to static assets in `public`.
76 | // For example,
.
77 | // This should only be used as an escape hatch. Normally you would put
78 | // images into the `src` and `import` them in code to get their paths.
79 | PUBLIC_URL: publicUrl,
80 | // We support configuring the sockjs pathname during development.
81 | // These settings let a developer run multiple simultaneous projects.
82 | // They are used as the connection `hostname`, `pathname` and `port`
83 | // in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
84 | // and `sockPort` options in webpack-dev-server.
85 | WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
86 | WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
87 | WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
88 | // Whether or not react-refresh is enabled.
89 | // react-refresh is not 100% stable at this time,
90 | // which is why it's disabled by default.
91 | // It is defined here so it is available in the webpackHotDevClient.
92 | FAST_REFRESH: process.env.FAST_REFRESH !== "false",
93 | }
94 | );
95 | // Stringify all values so we can feed into webpack DefinePlugin
96 | const stringified = {
97 | "process.env": Object.keys(raw).reduce((env, key) => {
98 | env[key] = JSON.stringify(raw[key]);
99 | return env;
100 | }, {}),
101 | __DEV__: true,
102 |
103 | __PROFILE__: true,
104 |
105 | __UMD__: true,
106 |
107 | __EXPERIMENTAL__: false,
108 |
109 | __VARIANT__: false,
110 | };
111 |
112 | return { raw, stringified };
113 | }
114 |
115 | module.exports = getClientEnvironment;
116 |
--------------------------------------------------------------------------------
/config/getHttpsConfig.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const crypto = require('crypto');
6 | const chalk = require('react-dev-utils/chalk');
7 | const paths = require('./paths');
8 |
9 | // Ensure the certificate and key provided are valid and if not
10 | // throw an easy to debug error
11 | function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
12 | let encrypted;
13 | try {
14 | // publicEncrypt will throw an error with an invalid cert
15 | encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
16 | } catch (err) {
17 | throw new Error(
18 | `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
19 | );
20 | }
21 |
22 | try {
23 | // privateDecrypt will throw an error with an invalid key
24 | crypto.privateDecrypt(key, encrypted);
25 | } catch (err) {
26 | throw new Error(
27 | `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
28 | err.message
29 | }`
30 | );
31 | }
32 | }
33 |
34 | // Read file and throw an error if it doesn't exist
35 | function readEnvFile(file, type) {
36 | if (!fs.existsSync(file)) {
37 | throw new Error(
38 | `You specified ${chalk.cyan(
39 | type
40 | )} in your env, but the file "${chalk.yellow(file)}" can't be found.`
41 | );
42 | }
43 | return fs.readFileSync(file);
44 | }
45 |
46 | // Get the https config
47 | // Return cert files if provided in env, otherwise just true or false
48 | function getHttpsConfig() {
49 | const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
50 | const isHttps = HTTPS === 'true';
51 |
52 | if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
53 | const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
54 | const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
55 | const config = {
56 | cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
57 | key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
58 | };
59 |
60 | validateKeyAndCerts({ ...config, keyFile, crtFile });
61 | return config;
62 | }
63 | return isHttps;
64 | }
65 |
66 | module.exports = getHttpsConfig;
67 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const camelcase = require('camelcase');
5 |
6 | // This is a custom Jest transformer turning file imports into filenames.
7 | // http://facebook.github.io/jest/docs/en/webpack.html
8 |
9 | module.exports = {
10 | process(src, filename) {
11 | const assetFilename = JSON.stringify(path.basename(filename));
12 |
13 | if (filename.match(/\.svg$/)) {
14 | // Based on how SVGR generates a component name:
15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16 | const pascalCaseFilename = camelcase(path.parse(filename).name, {
17 | pascalCase: true,
18 | });
19 | const componentName = `Svg${pascalCaseFilename}`;
20 | return `const React = require('react');
21 | module.exports = {
22 | __esModule: true,
23 | default: ${assetFilename},
24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
25 | return {
26 | $$typeof: Symbol.for('react.element'),
27 | type: 'svg',
28 | ref: ref,
29 | key: null,
30 | props: Object.assign({}, props, {
31 | children: ${assetFilename}
32 | })
33 | };
34 | }),
35 | };`;
36 | }
37 |
38 | return `module.exports = ${assetFilename};`;
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/config/modules.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const paths = require('./paths');
6 | const chalk = require('react-dev-utils/chalk');
7 | const resolve = require('resolve');
8 |
9 | /**
10 | * Get additional module paths based on the baseUrl of a compilerOptions object.
11 | *
12 | * @param {Object} options
13 | */
14 | function getAdditionalModulePaths(options = {}) {
15 | const baseUrl = options.baseUrl;
16 |
17 | if (!baseUrl) {
18 | return '';
19 | }
20 |
21 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
22 |
23 | // We don't need to do anything if `baseUrl` is set to `node_modules`. This is
24 | // the default behavior.
25 | if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
26 | return null;
27 | }
28 |
29 | // Allow the user set the `baseUrl` to `appSrc`.
30 | if (path.relative(paths.appSrc, baseUrlResolved) === '') {
31 | return [paths.appSrc];
32 | }
33 |
34 | // If the path is equal to the root directory we ignore it here.
35 | // We don't want to allow importing from the root directly as source files are
36 | // not transpiled outside of `src`. We do allow importing them with the
37 | // absolute path (e.g. `src/Components/Button.js`) but we set that up with
38 | // an alias.
39 | if (path.relative(paths.appPath, baseUrlResolved) === '') {
40 | return null;
41 | }
42 |
43 | // Otherwise, throw an error.
44 | throw new Error(
45 | chalk.red.bold(
46 | "Your project's `baseUrl` can only be set to `src` or `node_modules`." +
47 | ' Create React App does not support other values at this time.'
48 | )
49 | );
50 | }
51 |
52 | /**
53 | * Get webpack aliases based on the baseUrl of a compilerOptions object.
54 | *
55 | * @param {*} options
56 | */
57 | function getWebpackAliases(options = {}) {
58 | const baseUrl = options.baseUrl;
59 |
60 | if (!baseUrl) {
61 | return {};
62 | }
63 |
64 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
65 |
66 | if (path.relative(paths.appPath, baseUrlResolved) === '') {
67 | return {
68 | src: paths.appSrc,
69 | };
70 | }
71 | }
72 |
73 | /**
74 | * Get jest aliases based on the baseUrl of a compilerOptions object.
75 | *
76 | * @param {*} options
77 | */
78 | function getJestAliases(options = {}) {
79 | const baseUrl = options.baseUrl;
80 |
81 | if (!baseUrl) {
82 | return {};
83 | }
84 |
85 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
86 |
87 | if (path.relative(paths.appPath, baseUrlResolved) === '') {
88 | return {
89 | '^src/(.*)$': '/src/$1',
90 | };
91 | }
92 | }
93 |
94 | function getModules() {
95 | // Check if TypeScript is setup
96 | const hasTsConfig = fs.existsSync(paths.appTsConfig);
97 | const hasJsConfig = fs.existsSync(paths.appJsConfig);
98 |
99 | if (hasTsConfig && hasJsConfig) {
100 | throw new Error(
101 | 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
102 | );
103 | }
104 |
105 | let config;
106 |
107 | // If there's a tsconfig.json we assume it's a
108 | // TypeScript project and set up the config
109 | // based on tsconfig.json
110 | if (hasTsConfig) {
111 | const ts = require(resolve.sync('typescript', {
112 | basedir: paths.appNodeModules,
113 | }));
114 | config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
115 | // Otherwise we'll check if there is jsconfig.json
116 | // for non TS projects.
117 | } else if (hasJsConfig) {
118 | config = require(paths.appJsConfig);
119 | }
120 |
121 | config = config || {};
122 | const options = config.compilerOptions || {};
123 |
124 | const additionalModulePaths = getAdditionalModulePaths(options);
125 |
126 | return {
127 | additionalModulePaths: additionalModulePaths,
128 | webpackAliases: getWebpackAliases(options),
129 | jestAliases: getJestAliases(options),
130 | hasTsConfig,
131 | };
132 | }
133 |
134 | module.exports = getModules();
135 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebook/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
13 | // "public path" at which the app is served.
14 | // webpack needs to know it to put the right