Remove runtime dependency on prop-types (#18127)
* Remove runtime dep on prop-types * Fix test
Dan Abramov committed
Feb 28, 2020 at 01:21 UTC
d72700ff5a212262068df8ffa6bd2d68b04f9f54
16 files changed
+94
-74
packages/react-art/package.json
-1
@@ -26,7 +26,6 @@
26
"create-react-class": "^15.6.2",
27
"loose-envify": "^1.1.0",
28
"object-assign": "^4.1.1",
29
- "prop-types": "^15.6.2",
29
"scheduler": "^0.19.0"
30
},
31
"peerDependencies": {
packages/react-dom/package.json
-1
@@ -19,7 +19,6 @@
19
"dependencies": {
20
"loose-envify": "^1.1.0",
21
"object-assign": "^4.1.1",
22
- "prop-types": "^15.6.2",
22
"scheduler": "^0.19.0"
23
},
24
"peerDependencies": {
packages/react-dom/src/server/ReactPartialRendererContext.js
+2
-11
@@ -12,14 +12,11 @@ import type {ReactContext} from 'shared/ReactTypes';
12
13
import {disableLegacyContext} from 'shared/ReactFeatureFlags';
14
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
15
-import ReactSharedInternals from 'shared/ReactSharedInternals';
15
import getComponentName from 'shared/getComponentName';
17
-import checkPropTypes from 'prop-types/checkPropTypes';
16
+import checkPropTypes from 'shared/checkPropTypes';
17
19
-let ReactDebugCurrentFrame;
18
let didWarnAboutInvalidateContextType;
19
if (__DEV__) {
22
- ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
20
didWarnAboutInvalidateContextType = new Set();
21
}
22
@@ -42,13 +39,7 @@ function maskContext(type, context) {
39
40
function checkContextTypes(typeSpecs, values, location: string) {
41
if (__DEV__) {
45
- checkPropTypes(
46
- typeSpecs,
47
- values,
48
- location,
49
- 'Component',
50
- ReactDebugCurrentFrame.getCurrentStack,
51
- );
42
+ checkPropTypes(typeSpecs, values, location, 'Component');
43
}
44
}
45
packages/react-dom/src/shared/ReactControlledValuePropTypes.js
+1
-1
@@ -5,7 +5,7 @@
5
* LICENSE file in the root directory of this source tree.
6
*/
7
8
-import checkPropTypes from 'prop-types/checkPropTypes';
8
+import checkPropTypes from 'shared/checkPropTypes';
9
import ReactSharedInternals from 'shared/ReactSharedInternals';
10
import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';
11
packages/react-flight/package.json
+1
-2
@@ -29,8 +29,7 @@
29
},
30
"dependencies": {
31
"loose-envify": "^1.1.0",
32
- "object-assign": "^4.1.1",
33
- "prop-types": "^15.6.2"
32
+ "object-assign": "^4.1.1"
33
},
34
"browserify": {
35
"transform": [
packages/react-native-renderer/package.json
-1
@@ -9,7 +9,6 @@
9
},
10
"dependencies": {
11
"object-assign": "^4.1.1",
12
- "prop-types": "^15.6.2",
12
"scheduler": "^0.11.0"
13
},
14
"peerDependencies": {
packages/react-noop-renderer/package.json
-1
@@ -12,7 +12,6 @@
12
"license": "MIT",
13
"dependencies": {
14
"object-assign": "^4.1.1",
15
- "prop-types": "^15.6.2",
15
"regenerator-runtime": "^0.11.0",
16
"react-reconciler": "*",
17
"react-flight": "*",
packages/react-reconciler/package.json
-1
@@ -32,7 +32,6 @@
32
"dependencies": {
33
"loose-envify": "^1.1.0",
34
"object-assign": "^4.1.1",
35
- "prop-types": "^15.6.2",
35
"scheduler": "^0.19.0"
36
},
37
"browserify": {
packages/react-reconciler/src/ReactFiberBeginWork.js
+2
-17
@@ -18,7 +18,7 @@ import type {
18
} from './ReactFiberSuspenseComponent';
19
import type {SuspenseContext} from './ReactFiberSuspenseContext';
20
21
-import checkPropTypes from 'prop-types/checkPropTypes';
21
+import checkPropTypes from 'shared/checkPropTypes';
22
23
import {
24
IndeterminateComponent,
@@ -75,7 +75,6 @@ import {refineResolvedLazyComponent} from 'shared/ReactLazyComponent';
75
import {REACT_LAZY_TYPE, getIteratorFn} from 'shared/ReactSymbols';
76
import {
77
getCurrentFiberOwnerNameInDevOrNull,
78
- getCurrentFiberStackInDev,
78
setIsRendering,
79
} from './ReactCurrentFiber';
80
import {startWorkTimer, cancelWorkTimer} from './ReactDebugFiberPerf';
@@ -296,7 +295,6 @@ function updateForwardRef(
295
nextProps, // Resolved props
296
'prop',
297
getComponentName(Component),
299
- getCurrentFiberStackInDev,
298
);
299
}
300
}
@@ -414,7 +412,6 @@ function updateMemoComponent(
412
nextProps, // Resolved props
413
'prop',
414
getComponentName(type),
417
- getCurrentFiberStackInDev,
415
);
416
}
417
}
@@ -442,7 +439,6 @@ function updateMemoComponent(
439
nextProps, // Resolved props
440
'prop',
441
getComponentName(type),
445
- getCurrentFiberStackInDev,
442
);
443
}
444
}
@@ -501,7 +497,6 @@ function updateSimpleMemoComponent(
497
nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
498
'prop',
499
getComponentName(outerMemoType),
504
- getCurrentFiberStackInDev,
500
);
501
}
502
// Inner propTypes will be validated in the function component path.
@@ -626,7 +621,6 @@ function updateFunctionComponent(
621
nextProps, // Resolved props
622
'prop',
623
getComponentName(Component),
629
- getCurrentFiberStackInDev,
624
);
625
}
626
}
@@ -793,7 +787,6 @@ function updateClassComponent(
787
nextProps, // Resolved props
788
'prop',
789
getComponentName(Component),
796
- getCurrentFiberStackInDev,
790
);
791
}
792
}
@@ -1198,7 +1191,6 @@ function mountLazyComponent(
1191
resolvedProps, // Resolved for outer only
1192
'prop',
1193
getComponentName(Component),
1201
- getCurrentFiberStackInDev,
1194
);
1195
}
1196
}
@@ -2622,13 +2614,7 @@ function updateContextProvider(
2614
const providerPropTypes = workInProgress.type.propTypes;
2615
2616
if (providerPropTypes) {
2625
- checkPropTypes(
2626
- providerPropTypes,
2627
- newProps,
2628
- 'prop',
2629
- 'Context.Provider',
2630
- getCurrentFiberStackInDev,
2631
- );
2617
+ checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
2618
}
2619
}
2620
@@ -3208,7 +3194,6 @@ function beginWork(
3194
resolvedProps, // Resolved for outer only
3195
'prop',
3196
getComponentName(type),
3211
- getCurrentFiberStackInDev,
3197
);
3198
}
3199
}
packages/react-reconciler/src/ReactFiberContext.js
+3
-21
@@ -15,9 +15,8 @@ import {disableLegacyContext} from 'shared/ReactFeatureFlags';
15
import {ClassComponent, HostRoot} from 'shared/ReactWorkTags';
16
import getComponentName from 'shared/getComponentName';
17
import invariant from 'shared/invariant';
18
-import checkPropTypes from 'prop-types/checkPropTypes';
18
+import checkPropTypes from 'shared/checkPropTypes';
19
20
-import {getCurrentFiberStackInDev} from './ReactCurrentFiber';
20
import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
21
import {createCursor, push, pop} from './ReactFiberStack';
22
@@ -105,13 +104,7 @@ function getMaskedContext(
104
105
if (__DEV__) {
106
const name = getComponentName(type) || 'Unknown';
108
- checkPropTypes(
109
- contextTypes,
110
- context,
111
- 'context',
112
- name,
113
- getCurrentFiberStackInDev,
114
- );
107
+ checkPropTypes(contextTypes, context, 'context', name);
108
}
109
110
// Cache unmasked context so we can avoid recreating masked context unless necessary.
@@ -223,18 +216,7 @@ function processChildContext(
216
}
217
if (__DEV__) {
218
const name = getComponentName(type) || 'Unknown';
226
- checkPropTypes(
227
- childContextTypes,
228
- childContext,
229
- 'child context',
230
- name,
231
- // In practice, there is one case in which we won't get a stack. It's when
232
- // somebody calls unstable_renderSubtreeIntoContainer() and we process
233
- // context from the parent component instance. The stack will be missing
234
- // because it's outside of the reconciliation, and so the pointer has not
235
- // been set. This is rare and doesn't matter. We'll also remove that API.
236
- getCurrentFiberStackInDev,
237
- );
219
+ checkPropTypes(childContextTypes, childContext, 'child context', name);
220
}
221
222
return {...parentContext, ...childContext};
packages/react-server/package.json
+1
-2
@@ -30,8 +30,7 @@
30
},
31
"dependencies": {
32
"loose-envify": "^1.1.0",
33
- "object-assign": "^4.1.1",
34
- "prop-types": "^15.6.2"
33
+ "object-assign": "^4.1.1"
34
},
35
"browserify": {
36
"transform": [
packages/react-test-renderer/package.json
-1
@@ -20,7 +20,6 @@
20
"homepage": "https://reactjs.org/",
21
"dependencies": {
22
"object-assign": "^4.1.1",
23
- "prop-types": "^15.6.2",
23
"react-is": "^16.8.6",
24
"react-shallow-renderer": "^16.12.0",
25
"scheduler": "^0.19.0"
packages/react/package.json
+1
-2
@@ -27,8 +27,7 @@
27
},
28
"dependencies": {
29
"loose-envify": "^1.1.0",
30
- "object-assign": "^4.1.1",
31
- "prop-types": "^15.6.2"
30
+ "object-assign": "^4.1.1"
31
},
32
"browserify": {
33
"transform": [
packages/react/src/ReactElementValidator.js
+3
-11
@@ -22,7 +22,7 @@ import {
22
REACT_ELEMENT_TYPE,
23
} from 'shared/ReactSymbols';
24
import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
25
-import checkPropTypes from 'prop-types/checkPropTypes';
25
+import checkPropTypes from 'shared/checkPropTypes';
26
27
import ReactCurrentOwner from './ReactCurrentOwner';
28
import {
@@ -31,9 +31,7 @@ import {
31
cloneElement,
32
jsxDEV,
33
} from './ReactElement';
34
-import ReactDebugCurrentFrame, {
35
- setCurrentlyValidatingElement,
36
-} from './ReactDebugCurrentFrame';
34
+import {setCurrentlyValidatingElement} from './ReactDebugCurrentFrame';
35
36
let propTypesMisspellWarningShown;
37
@@ -213,13 +211,7 @@ function validatePropTypes(element) {
211
}
212
if (propTypes) {
213
setCurrentlyValidatingElement(element);
216
- checkPropTypes(
217
- propTypes,
218
- element.props,
219
- 'prop',
220
- name,
221
- ReactDebugCurrentFrame.getStackAddendum,
222
- );
214
+ checkPropTypes(propTypes, element.props, 'prop', name);
215
setCurrentlyValidatingElement(null);
216
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
217
propTypesMisspellWarningShown = true;
packages/react/src/__tests__/ReactElementValidator-test.internal.js
-1
@@ -399,7 +399,6 @@ describe('ReactElementValidator', () => {
399
'returned a function. You may have forgotten to pass an argument to ' +
400
'the type checker creator (arrayOf, instanceOf, objectOf, oneOf, ' +
401
'oneOfType, and shape all require an argument).',
402
- {withoutStack: true},
402
);
403
});
404
packages/shared/checkPropTypes.js
new
+80
@@ -0,0 +1,80 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+let loggedTypeFailures = {};
11
+
12
+export default function checkPropTypes(
13
+ typeSpecs: Object,
14
+ values: Object,
15
+ location: string,
16
+ componentName: ?string,
17
+): void {
18
+ if (__DEV__) {
19
+ // $FlowFixMe This is okay but Flow doesn't know it.
20
+ let has = Function.call.bind(Object.prototype.hasOwnProperty);
21
+ for (let typeSpecName in typeSpecs) {
22
+ if (has(typeSpecs, typeSpecName)) {
23
+ let error;
24
+ // Prop type validation may throw. In case they do, we don't want to
25
+ // fail the render phase where it didn't fail before. So we log it.
26
+ // After these have been cleaned up, we'll let them throw.
27
+ try {
28
+ // This is intentionally an invariant that gets caught. It's the same
29
+ // behavior as without this statement except with a better message.
30
+ if (typeof typeSpecs[typeSpecName] !== 'function') {
31
+ let err = Error(
32
+ (componentName || 'React class') +
33
+ ': ' +
34
+ location +
35
+ ' type `' +
36
+ typeSpecName +
37
+ '` is invalid; ' +
38
+ 'it must be a function, usually from the `prop-types` package, but received `' +
39
+ typeof typeSpecs[typeSpecName] +
40
+ '`.' +
41
+ 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.',
42
+ );
43
+ err.name = 'Invariant Violation';
44
+ throw err;
45
+ }
46
+ error = typeSpecs[typeSpecName](
47
+ values,
48
+ typeSpecName,
49
+ componentName,
50
+ location,
51
+ null,
52
+ 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED',
53
+ );
54
+ } catch (ex) {
55
+ error = ex;
56
+ }
57
+ if (error && !(error instanceof Error)) {
58
+ console.error(
59
+ '%s: type specification of %s' +
60
+ ' `%s` is invalid; the type checker ' +
61
+ 'function must return `null` or an `Error` but returned a %s. ' +
62
+ 'You may have forgotten to pass an argument to the type checker ' +
63
+ 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
64
+ 'shape all require an argument).',
65
+ componentName || 'React class',
66
+ location,
67
+ typeSpecName,
68
+ typeof error,
69
+ );
70
+ }
71
+ if (error instanceof Error && !(error.message in loggedTypeFailures)) {
72
+ // Only monitor this failure once because there tends to be a lot of the
73
+ // same error.
74
+ loggedTypeFailures[error.message] = true;
75
+ console.error('Failed %s type: %s', location, error.message);
76
+ }
77
+ }
78
+ }
79
+ }
80
+}