Skip to content

Commit

Permalink
Remove runtime dependency on prop-types (#18127)
Browse files Browse the repository at this point in the history
* Remove runtime dep on prop-types

* Fix test
  • Loading branch information
gaearon committed Feb 28, 2020
1 parent 549e418 commit d72700f
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 74 deletions.
1 change: 0 additions & 1 deletion packages/react-art/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"create-react-class": "^15.6.2",
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.0"
},
"peerDependencies": {
Expand Down
1 change: 0 additions & 1 deletion packages/react-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.0"
},
"peerDependencies": {
Expand Down
13 changes: 2 additions & 11 deletions packages/react-dom/src/server/ReactPartialRendererContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@ import type {ReactContext} from 'shared/ReactTypes';

import {disableLegacyContext} from 'shared/ReactFeatureFlags';
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentName from 'shared/getComponentName';
import checkPropTypes from 'prop-types/checkPropTypes';
import checkPropTypes from 'shared/checkPropTypes';

let ReactDebugCurrentFrame;
let didWarnAboutInvalidateContextType;
if (__DEV__) {
ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
didWarnAboutInvalidateContextType = new Set();
}

Expand All @@ -42,13 +39,7 @@ function maskContext(type, context) {

function checkContextTypes(typeSpecs, values, location: string) {
if (__DEV__) {
checkPropTypes(
typeSpecs,
values,
location,
'Component',
ReactDebugCurrentFrame.getCurrentStack,
);
checkPropTypes(typeSpecs, values, location, 'Component');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import checkPropTypes from 'prop-types/checkPropTypes';
import checkPropTypes from 'shared/checkPropTypes';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';

Expand Down
3 changes: 1 addition & 2 deletions packages/react-flight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
},
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
"object-assign": "^4.1.1"
},
"browserify": {
"transform": [
Expand Down
1 change: 0 additions & 1 deletion packages/react-native-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
},
"dependencies": {
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.11.0"
},
"peerDependencies": {
Expand Down
1 change: 0 additions & 1 deletion packages/react-noop-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"license": "MIT",
"dependencies": {
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"regenerator-runtime": "^0.11.0",
"react-reconciler": "*",
"react-flight": "*",
Expand Down
1 change: 0 additions & 1 deletion packages/react-reconciler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.0"
},
"browserify": {
Expand Down
19 changes: 2 additions & 17 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type {
} from './ReactFiberSuspenseComponent';
import type {SuspenseContext} from './ReactFiberSuspenseContext';

import checkPropTypes from 'prop-types/checkPropTypes';
import checkPropTypes from 'shared/checkPropTypes';

import {
IndeterminateComponent,
Expand Down Expand Up @@ -75,7 +75,6 @@ import {refineResolvedLazyComponent} from 'shared/ReactLazyComponent';
import {REACT_LAZY_TYPE, getIteratorFn} from 'shared/ReactSymbols';
import {
getCurrentFiberOwnerNameInDevOrNull,
getCurrentFiberStackInDev,
setIsRendering,
} from './ReactCurrentFiber';
import {startWorkTimer, cancelWorkTimer} from './ReactDebugFiberPerf';
Expand Down Expand Up @@ -296,7 +295,6 @@ function updateForwardRef(
nextProps, // Resolved props
'prop',
getComponentName(Component),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -414,7 +412,6 @@ function updateMemoComponent(
nextProps, // Resolved props
'prop',
getComponentName(type),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -442,7 +439,6 @@ function updateMemoComponent(
nextProps, // Resolved props
'prop',
getComponentName(type),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -501,7 +497,6 @@ function updateSimpleMemoComponent(
nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
'prop',
getComponentName(outerMemoType),
getCurrentFiberStackInDev,
);
}
// Inner propTypes will be validated in the function component path.
Expand Down Expand Up @@ -626,7 +621,6 @@ function updateFunctionComponent(
nextProps, // Resolved props
'prop',
getComponentName(Component),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -793,7 +787,6 @@ function updateClassComponent(
nextProps, // Resolved props
'prop',
getComponentName(Component),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -1198,7 +1191,6 @@ function mountLazyComponent(
resolvedProps, // Resolved for outer only
'prop',
getComponentName(Component),
getCurrentFiberStackInDev,
);
}
}
Expand Down Expand Up @@ -2622,13 +2614,7 @@ function updateContextProvider(
const providerPropTypes = workInProgress.type.propTypes;

if (providerPropTypes) {
checkPropTypes(
providerPropTypes,
newProps,
'prop',
'Context.Provider',
getCurrentFiberStackInDev,
);
checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
}
}

Expand Down Expand Up @@ -3208,7 +3194,6 @@ function beginWork(
resolvedProps, // Resolved for outer only
'prop',
getComponentName(type),
getCurrentFiberStackInDev,
);
}
}
Expand Down
24 changes: 3 additions & 21 deletions packages/react-reconciler/src/ReactFiberContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import {disableLegacyContext} from 'shared/ReactFeatureFlags';
import {ClassComponent, HostRoot} from 'shared/ReactWorkTags';
import getComponentName from 'shared/getComponentName';
import invariant from 'shared/invariant';
import checkPropTypes from 'prop-types/checkPropTypes';
import checkPropTypes from 'shared/checkPropTypes';

import {getCurrentFiberStackInDev} from './ReactCurrentFiber';
import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
import {createCursor, push, pop} from './ReactFiberStack';

Expand Down Expand Up @@ -105,13 +104,7 @@ function getMaskedContext(

if (__DEV__) {
const name = getComponentName(type) || 'Unknown';
checkPropTypes(
contextTypes,
context,
'context',
name,
getCurrentFiberStackInDev,
);
checkPropTypes(contextTypes, context, 'context', name);
}

// Cache unmasked context so we can avoid recreating masked context unless necessary.
Expand Down Expand Up @@ -223,18 +216,7 @@ function processChildContext(
}
if (__DEV__) {
const name = getComponentName(type) || 'Unknown';
checkPropTypes(
childContextTypes,
childContext,
'child context',
name,
// In practice, there is one case in which we won't get a stack. It's when
// somebody calls unstable_renderSubtreeIntoContainer() and we process
// context from the parent component instance. The stack will be missing
// because it's outside of the reconciliation, and so the pointer has not
// been set. This is rare and doesn't matter. We'll also remove that API.
getCurrentFiberStackInDev,
);
checkPropTypes(childContextTypes, childContext, 'child context', name);
}

return {...parentContext, ...childContext};
Expand Down
3 changes: 1 addition & 2 deletions packages/react-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
},
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
"object-assign": "^4.1.1"
},
"browserify": {
"transform": [
Expand Down
1 change: 0 additions & 1 deletion packages/react-test-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"homepage": "https://reactjs.org/",
"dependencies": {
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"react-is": "^16.8.6",
"react-shallow-renderer": "^16.12.0",
"scheduler": "^0.19.0"
Expand Down
3 changes: 1 addition & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
},
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
"object-assign": "^4.1.1"
},
"browserify": {
"transform": [
Expand Down
14 changes: 3 additions & 11 deletions packages/react/src/ReactElementValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
REACT_ELEMENT_TYPE,
} from 'shared/ReactSymbols';
import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
import checkPropTypes from 'prop-types/checkPropTypes';
import checkPropTypes from 'shared/checkPropTypes';

import ReactCurrentOwner from './ReactCurrentOwner';
import {
Expand All @@ -31,9 +31,7 @@ import {
cloneElement,
jsxDEV,
} from './ReactElement';
import ReactDebugCurrentFrame, {
setCurrentlyValidatingElement,
} from './ReactDebugCurrentFrame';
import {setCurrentlyValidatingElement} from './ReactDebugCurrentFrame';

let propTypesMisspellWarningShown;

Expand Down Expand Up @@ -213,13 +211,7 @@ function validatePropTypes(element) {
}
if (propTypes) {
setCurrentlyValidatingElement(element);
checkPropTypes(
propTypes,
element.props,
'prop',
name,
ReactDebugCurrentFrame.getStackAddendum,
);
checkPropTypes(propTypes, element.props, 'prop', name);
setCurrentlyValidatingElement(null);
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
propTypesMisspellWarningShown = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ describe('ReactElementValidator', () => {
'returned a function. You may have forgotten to pass an argument to ' +
'the type checker creator (arrayOf, instanceOf, objectOf, oneOf, ' +
'oneOfType, and shape all require an argument).',
{withoutStack: true},
);
});

Expand Down
80 changes: 80 additions & 0 deletions packages/shared/checkPropTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

let loggedTypeFailures = {};

export default function checkPropTypes(
typeSpecs: Object,
values: Object,
location: string,
componentName: ?string,
): void {
if (__DEV__) {
// $FlowFixMe This is okay but Flow doesn't know it.
let has = Function.call.bind(Object.prototype.hasOwnProperty);
for (let typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
let error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
if (typeof typeSpecs[typeSpecName] !== 'function') {
let err = Error(
(componentName || 'React class') +
': ' +
location +
' type `' +
typeSpecName +
'` is invalid; ' +
'it must be a function, usually from the `prop-types` package, but received `' +
typeof typeSpecs[typeSpecName] +
'`.' +
'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.',
);
err.name = 'Invariant Violation';
throw err;
}
error = typeSpecs[typeSpecName](
values,
typeSpecName,
componentName,
location,
null,
'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED',
);
} catch (ex) {
error = ex;
}
if (error && !(error instanceof Error)) {
console.error(
'%s: type specification of %s' +
' `%s` is invalid; the type checker ' +
'function must return `null` or an `Error` but returned a %s. ' +
'You may have forgotten to pass an argument to the type checker ' +
'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
'shape all require an argument).',
componentName || 'React class',
location,
typeSpecName,
typeof error,
);
}
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
console.error('Failed %s type: %s', location, error.message);
}
}
}
}
}

0 comments on commit d72700f

Please sign in to comment.