Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove runtime dependency on prop-types #18127

Merged
merged 2 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
}
}
}