From cb6886417a1383d389b56c23118a5be450ca027a Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Wed, 24 May 2017 08:07:56 -0700 Subject: [PATCH] Downgrade deprecation error to warning **what is the change?:** Inlines a version of 'warning' that uses `console.warn` instead of `console.error`, and then uses that for the deprecation warning. **NOTE: I'm not sure that this will only warn in development, which is a problem. We don't seem to have a '__DEV__' env. variable set up here, so I'm not sure how to limit the warnings to development?** **why make this change?:** This is a particularly noisy warning that was firing in 3rd party libraries, which then causes it to show up in product code. Users then can't silence it easily without updating their library. This makes it slightly less painful, hopefully, but still painful enough to get folks to update their code. **test plan:** `yarn test` - updated some tests to check for this. **issue:** https://github.com/facebook/react/issues/9398 --- __tests__/PropTypesDevelopmentReact15.js | 26 ++++++++++---------- factoryWithTypeCheckers.js | 30 +++++++++++++++++++++++- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/__tests__/PropTypesDevelopmentReact15.js b/__tests__/PropTypesDevelopmentReact15.js index e98a7bf..a126692 100644 --- a/__tests__/PropTypesDevelopmentReact15.js +++ b/__tests__/PropTypesDevelopmentReact15.js @@ -100,11 +100,11 @@ function expectWarningInDevelopment(declaration, value) { for (var i = 0; i < 3; i++) { declaration(props, propName, componentName, 'prop'); } - expect(console.error.calls.count()).toBe(1); - expect(console.error.calls.argsFor(0)[0]).toContain( + expect(console.warn.calls.count()).toBe(1); + expect(console.warn.calls.argsFor(0)[0]).toContain( 'You are manually calling a React.PropTypes validation ', ); - console.error.calls.reset(); + console.warn.calls.reset(); } describe('PropTypesDevelopmentReact15', () => { @@ -223,7 +223,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.array, /please/); expectWarningInDevelopment(PropTypes.array, []); expectWarningInDevelopment(PropTypes.array.isRequired, /please/); @@ -287,7 +287,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.any, null); expectWarningInDevelopment(PropTypes.any.isRequired, null); expectWarningInDevelopment(PropTypes.any.isRequired, undefined); @@ -383,7 +383,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.arrayOf({foo: PropTypes.string}), { foo: 'bar', }); @@ -450,7 +450,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.element, [
,
]); expectWarningInDevelopment(PropTypes.element,
); expectWarningInDevelopment(PropTypes.element, 123); @@ -549,7 +549,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.instanceOf(Date), {}); expectWarningInDevelopment(PropTypes.instanceOf(Date), new Date()); expectWarningInDevelopment(PropTypes.instanceOf(Date).isRequired, {}); @@ -649,7 +649,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.node, 'node'); expectWarningInDevelopment(PropTypes.node, {}); expectWarningInDevelopment(PropTypes.node.isRequired, 'node'); @@ -764,7 +764,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.objectOf({foo: PropTypes.string}), { foo: 'bar', }); @@ -839,7 +839,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), true); expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), null); expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), undefined); @@ -930,7 +930,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment( PropTypes.oneOfType([PropTypes.string, PropTypes.number]), [], @@ -1028,7 +1028,7 @@ describe('PropTypesDevelopmentReact15', () => { }); it('should warn if called manually in development', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); expectWarningInDevelopment(PropTypes.shape({}), 'some string'); expectWarningInDevelopment(PropTypes.shape({foo: PropTypes.number}), { foo: 42, diff --git a/factoryWithTypeCheckers.js b/factoryWithTypeCheckers.js index 4da647e..d2de3cb 100644 --- a/factoryWithTypeCheckers.js +++ b/factoryWithTypeCheckers.js @@ -16,6 +16,34 @@ var warning = require('fbjs/lib/warning'); var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret'); var checkPropTypes = require('./checkPropTypes'); +// We are inlining 'lowPriorityWarning' until it gets added to 'fbjs' +// https://github.com/facebook/fbjs/issues/239 +const printWarning = function(format, ...args) { + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); + if (typeof console !== 'undefined') { + console.warn(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} +}; + +const lowPriorityWarning = function(condition, format, ...args) { + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + if (!condition) { + printWarning(format, ...args); + } +}; + module.exports = function(isValidElement, throwOnDirectAccess) { /* global Symbol */ var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; @@ -171,7 +199,7 @@ module.exports = function(isValidElement, throwOnDirectAccess) { // Avoid spamming the console because they are often not actionable except for lib authors manualPropTypeWarningCount < 3 ) { - warning( + lowPriorityWarning( false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' +