diff --git a/scripts/rollup/modules.js b/scripts/rollup/modules.js index e078fd6ce6023..468353360c47c 100644 --- a/scripts/rollup/modules.js +++ b/scripts/rollup/modules.js @@ -162,6 +162,7 @@ function getExternalModules(externals, bundleType, isRenderer) { case FB_PROD: fbjsModules.forEach(module => externalModules.push(module)); externalModules.push('ReactCurrentOwner'); + externalModules.push('lowPriorityWarning'); if (isRenderer) { externalModules.push('React'); if (externalModules.indexOf('react-dom') > -1) { diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index a7d6f88cb6bf6..cf53762037bd6 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -1,92 +1,92 @@ { "bundleSizes": { "react.development.js (UMD_DEV)": { - "size": 123496, - "gzip": 31034 + "size": 125119, + "gzip": 31339 }, "react.production.min.js (UMD_PROD)": { "size": 15753, "gzip": 5824 }, "react-dom.development.js (UMD_DEV)": { - "size": 592317, - "gzip": 136560 + "size": 593408, + "gzip": 136701 }, "react-dom.production.min.js (UMD_PROD)": { - "size": 121979, - "gzip": 38564 + "size": 122214, + "gzip": 38682 }, "react-dom-server.development.js (UMD_DEV)": { - "size": 498439, - "gzip": 120624 + "size": 525896, + "gzip": 126687 }, "react-dom-server.production.min.js (UMD_PROD)": { - "size": 107169, - "gzip": 33472 + "size": 111581, + "gzip": 34959 }, "react-art.development.js (UMD_DEV)": { - "size": 349177, - "gzip": 77902 + "size": 349191, + "gzip": 77905 }, "react-art.production.min.js (UMD_PROD)": { - "size": 96267, - "gzip": 29310 + "size": 96277, + "gzip": 29313 }, "react.development.js (NODE_DEV)": { - "size": 70293, - "gzip": 17777 + "size": 71914, + "gzip": 18276 }, "react.production.min.js (NODE_PROD)": { "size": 9195, "gzip": 3614 }, "React-dev.js (FB_DEV)": { - "size": 71576, - "gzip": 18181 + "size": 73423, + "gzip": 18751 }, "React-prod.js (FB_PROD)": { - "size": 36456, - "gzip": 9216 + "size": 36836, + "gzip": 9248 }, "ReactDOMStack-dev.js (FB_DEV)": { - "size": 494069, - "gzip": 117876 + "size": 496986, + "gzip": 118763 }, "ReactDOMStack-prod.js (FB_PROD)": { - "size": 352489, - "gzip": 84575 + "size": 353129, + "gzip": 84773 }, "react-dom.development.js (NODE_DEV)": { - "size": 549893, - "gzip": 126464 + "size": 550984, + "gzip": 126642 }, "react-dom.production.min.js (NODE_PROD)": { - "size": 118192, - "gzip": 37224 + "size": 118427, + "gzip": 37300 }, "ReactDOMFiber-dev.js (FB_DEV)": { - "size": 550815, - "gzip": 126958 + "size": 551962, + "gzip": 127141 }, "ReactDOMFiber-prod.js (FB_PROD)": { - "size": 410570, - "gzip": 94005 + "size": 411657, + "gzip": 94084 }, "react-dom-server.development.js (NODE_DEV)": { - "size": 447050, - "gzip": 108025 + "size": 474459, + "gzip": 114087 }, "react-dom-server.production.min.js (NODE_PROD)": { - "size": 101542, - "gzip": 31424 + "size": 105956, + "gzip": 32782 }, "ReactDOMServerStack-dev.js (FB_DEV)": { - "size": 445736, - "gzip": 107878 + "size": 455985, + "gzip": 109831 }, "ReactDOMServerStack-prod.js (FB_PROD)": { - "size": 333450, - "gzip": 80260 + "size": 334090, + "gzip": 80459 }, "ReactARTStack-dev.js (FB_DEV)": { "size": 143166, @@ -97,20 +97,20 @@ "gzip": 23039 }, "react-art.development.js (NODE_DEV)": { - "size": 270501, - "gzip": 57767 + "size": 270515, + "gzip": 57772 }, "react-art.production.min.js (NODE_PROD)": { - "size": 57652, - "gzip": 17386 + "size": 57662, + "gzip": 17391 }, "ReactARTFiber-dev.js (FB_DEV)": { - "size": 269759, - "gzip": 57590 + "size": 269773, + "gzip": 57593 }, "ReactARTFiber-prod.js (FB_PROD)": { - "size": 208039, - "gzip": 43486 + "size": 208053, + "gzip": 43488 }, "ReactNativeStack.js (RN)": { "size": 233993, @@ -121,20 +121,20 @@ "gzip": 84001 }, "ReactTestRendererFiber-dev.js (FB_DEV)": { - "size": 267261, - "gzip": 56462 + "size": 267275, + "gzip": 56465 }, "ReactTestRendererStack-dev.js (FB_DEV)": { "size": 151770, "gzip": 34846 }, "react-noop-renderer.development.js (NODE_DEV)": { - "size": 259178, - "gzip": 54431 + "size": 259192, + "gzip": 54435 }, "react-test-renderer.development.js (NODE_DEV)": { - "size": 268012, - "gzip": 56651 + "size": 268026, + "gzip": 56654 }, "react-dom-test-utils.development.js (NODE_DEV)": { "size": 52792, @@ -155,6 +155,14 @@ "ReactShallowRenderer-dev.js (FB_DEV)": { "size": 8063, "gzip": 2229 + }, + "ReactDOMServerStream-dev.js (FB_DEV)": { + "size": 472917, + "gzip": 113925 + }, + "ReactDOMServerStream-prod.js (FB_PROD)": { + "size": 345920, + "gzip": 83497 } } } \ No newline at end of file diff --git a/src/addons/__tests__/ReactDOMFactories-test.js b/src/addons/__tests__/ReactDOMFactories-test.js index b4a7a78ceda57..641faa3f003dd 100644 --- a/src/addons/__tests__/ReactDOMFactories-test.js +++ b/src/addons/__tests__/ReactDOMFactories-test.js @@ -17,13 +17,15 @@ var {div} = require('ReactDOMFactories'); describe('ReactDOMFactories', () => { it('allow factories to be called without warnings', () => { spyOn(console, 'error'); + spyOn(console, 'warn'); var element = div(); expect(element.type).toBe('div'); expect(console.error).not.toHaveBeenCalled(); + expect(console.warn).not.toHaveBeenCalled(); }); it('warns once when accessing React.DOM methods', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); var a = React.DOM.a(); var p = React.DOM.p(); @@ -31,8 +33,8 @@ describe('ReactDOMFactories', () => { expect(a.type).toBe('a'); expect(p.type).toBe('p'); - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error.calls.first().args[0]).toContain( + expect(console.warn).toHaveBeenCalledTimes(1); + expect(console.warn.calls.first().args[0]).toContain( 'Warning: Accessing factories like React.DOM.a has been deprecated', ); }); diff --git a/src/isomorphic/React.js b/src/isomorphic/React.js index ceb52dfa68d35..8335945752b60 100644 --- a/src/isomorphic/React.js +++ b/src/isomorphic/React.js @@ -27,7 +27,7 @@ var createFactory = ReactElement.createFactory; var cloneElement = ReactElement.cloneElement; if (__DEV__) { - var warning = require('fbjs/lib/warning'); + var lowPriorityWarning = require('lowPriorityWarning'); var canDefineProperty = require('canDefineProperty'); var ReactElementValidator = require('ReactElementValidator'); createElement = ReactElementValidator.createElement; @@ -91,7 +91,7 @@ if (__DEV__) { let warnedForPropTypes = false; React.createMixin = function(mixin) { - warning( + lowPriorityWarning( warnedForCreateMixin, 'React.createMixin is deprecated and should not be used. You ' + 'can use this mixin directly instead.', @@ -104,7 +104,7 @@ if (__DEV__) { if (canDefineProperty) { Object.defineProperty(React, 'checkPropTypes', { get() { - warning( + lowPriorityWarning( warnedForCheckPropTypes, 'checkPropTypes has been moved to a separate package. ' + 'Accessing React.checkPropTypes is no longer supported ' + @@ -119,7 +119,7 @@ if (__DEV__) { Object.defineProperty(React, 'createClass', { get: function() { - warning( + lowPriorityWarning( warnedForCreateClass, 'React.createClass is no longer supported. Use a plain JavaScript ' + "class instead. If you're not yet ready to migrate, " + @@ -133,7 +133,7 @@ if (__DEV__) { Object.defineProperty(React, 'PropTypes', { get() { - warning( + lowPriorityWarning( warnedForPropTypes, 'PropTypes has been moved to a separate package. ' + 'Accessing React.PropTypes is no longer supported ' + @@ -155,7 +155,7 @@ if (__DEV__) { Object.keys(ReactDOMFactories).forEach(function(factory) { React.DOM[factory] = function(...args) { if (!warnedForFactories) { - warning( + lowPriorityWarning( false, 'Accessing factories like React.DOM.%s has been deprecated ' + 'and will be removed in the future. Use the ' + diff --git a/src/isomorphic/__tests__/React-test.js b/src/isomorphic/__tests__/React-test.js index bd5d5bc1aaa4b..86e574a859636 100644 --- a/src/isomorphic/__tests__/React-test.js +++ b/src/isomorphic/__tests__/React-test.js @@ -19,22 +19,22 @@ describe('React', () => { }); it('should log a deprecation warning once when using React.createMixin', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); React.createMixin(); React.createMixin(); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( 'React.createMixin is deprecated and should not be used', ); }); it('should warn once when attempting to access React.createClass', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); let createClass = React.createClass; createClass = React.createClass; expect(createClass).not.toBe(undefined); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( 'React.createClass is no longer supported. Use a plain JavaScript ' + "class instead. If you're not yet ready to migrate, " + 'create-react-class is available on npm as a drop-in replacement. ' + @@ -43,12 +43,12 @@ describe('React', () => { }); it('should warn once when attempting to access React.PropTypes', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); let PropTypes = React.PropTypes; PropTypes = React.PropTypes; expect(PropTypes).not.toBe(undefined); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( 'PropTypes has been moved to a separate package. ' + 'Accessing React.PropTypes is no longer supported ' + 'and will be removed completely in React 16. ' + @@ -58,12 +58,12 @@ describe('React', () => { }); it('should warn once when attempting to access React.checkPropTypes', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); let checkPropTypes = React.checkPropTypes; checkPropTypes = React.checkPropTypes; expect(checkPropTypes).not.toBe(undefined); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( 'checkPropTypes has been moved to a separate package. ' + 'Accessing React.checkPropTypes is no longer supported ' + 'and will be removed completely in React 16. ' + diff --git a/src/isomorphic/classic/element/ReactElementValidator.js b/src/isomorphic/classic/element/ReactElementValidator.js index ea919f3a35caf..30d255513f206 100644 --- a/src/isomorphic/classic/element/ReactElementValidator.js +++ b/src/isomorphic/classic/element/ReactElementValidator.js @@ -27,8 +27,9 @@ var getIteratorFn = require('getIteratorFn'); if (__DEV__) { var checkPropTypes = require('prop-types/checkPropTypes'); - var warning = require('fbjs/lib/warning'); + var lowPriorityWarning = require('lowPriorityWarning'); var ReactDebugCurrentFrame = require('ReactDebugCurrentFrame'); + var warning = require('fbjs/lib/warning'); var {getCurrentStackAddendum} = require('ReactComponentTreeHook'); } @@ -285,7 +286,7 @@ var ReactElementValidator = { Object.defineProperty(validatedFactory, 'type', { enumerable: false, get: function() { - warning( + lowPriorityWarning( false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.', diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index 69bb8fd512b8d..969b4de9b6fbb 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -441,20 +441,20 @@ describe('ReactElementValidator', () => { }); it('should warn when accessing .type on an element factory', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); function TestComponent() { return
; } var TestFactory = React.createFactory(TestComponent); expect(TestFactory.type).toBe(TestComponent); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toBe( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toBe( 'Warning: Factory.type is deprecated. Access the class directly before ' + 'passing it to createFactory.', ); // Warn once, not again expect(TestFactory.type).toBe(TestComponent); - expectDev(console.error.calls.count()).toBe(1); + expectDev(console.warn.calls.count()).toBe(1); }); it('does not warn when using DOM node as children', () => { diff --git a/src/isomorphic/modern/class/ReactBaseClasses.js b/src/isomorphic/modern/class/ReactBaseClasses.js index 7397d8a49d8d1..4d17ace2bce56 100644 --- a/src/isomorphic/modern/class/ReactBaseClasses.js +++ b/src/isomorphic/modern/class/ReactBaseClasses.js @@ -16,7 +16,7 @@ var ReactNoopUpdateQueue = require('ReactNoopUpdateQueue'); var canDefineProperty = require('canDefineProperty'); var emptyObject = require('fbjs/lib/emptyObject'); var invariant = require('fbjs/lib/invariant'); -var warning = require('fbjs/lib/warning'); +var lowPriorityWarning = require('lowPriorityWarning'); /** * Base class helpers for the updating state of a component. @@ -108,7 +108,7 @@ if (__DEV__) { if (canDefineProperty) { Object.defineProperty(ReactComponent.prototype, methodName, { get: function() { - warning( + lowPriorityWarning( false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], diff --git a/src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee b/src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee index 15f5e46eab758..3def0950b2c50 100644 --- a/src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee +++ b/src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee @@ -378,16 +378,16 @@ describe 'ReactCoffeeScriptClass', -> undefined it 'should throw AND warn when trying to access classic APIs', -> - spyOn console, 'error' + spyOn console, 'warn' instance = test Inner(name: 'foo'), 'DIV', 'foo' expect(-> instance.replaceState {}).toThrow() expect(-> instance.isMounted()).toThrow() - expect(console.error.calls.count()).toBe 2 - expect(console.error.calls.argsFor(0)[0]).toContain( + expect(console.warn.calls.count()).toBe 2 + expect(console.warn.calls.argsFor(0)[0]).toContain( 'replaceState(...) is deprecated in plain JavaScript React classes' ) - expect(console.error.calls.argsFor(1)[0]).toContain( + expect(console.warn.calls.argsFor(1)[0]).toContain( 'isMounted(...) is deprecated in plain JavaScript React classes' ) undefined diff --git a/src/isomorphic/modern/class/__tests__/ReactES6Class-test.js b/src/isomorphic/modern/class/__tests__/ReactES6Class-test.js index f634e1d1c58d4..29d94221a722d 100644 --- a/src/isomorphic/modern/class/__tests__/ReactES6Class-test.js +++ b/src/isomorphic/modern/class/__tests__/ReactES6Class-test.js @@ -402,15 +402,15 @@ describe('ReactES6Class', () => { }); it('should throw AND warn when trying to access classic APIs', () => { - spyOn(console, 'error'); + spyOn(console, 'warn'); var instance = test(, 'DIV', 'foo'); expect(() => instance.replaceState({})).toThrow(); expect(() => instance.isMounted()).toThrow(); - expect(console.error.calls.count()).toBe(2); - expect(console.error.calls.argsFor(0)[0]).toContain( + expect(console.warn.calls.count()).toBe(2); + expect(console.warn.calls.argsFor(0)[0]).toContain( 'replaceState(...) is deprecated in plain JavaScript React classes', ); - expect(console.error.calls.argsFor(1)[0]).toContain( + expect(console.warn.calls.argsFor(1)[0]).toContain( 'isMounted(...) is deprecated in plain JavaScript React classes', ); }); diff --git a/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts b/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts index 33085c89d9213..66d5cd33631c1 100644 --- a/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts +++ b/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts @@ -502,18 +502,18 @@ describe('ReactTypeScriptClass', function() { }); it('should throw AND warn when trying to access classic APIs', function() { - spyOn(console, 'error'); + spyOn(console, 'warn'); var instance = test( React.createElement(Inner, {name: 'foo'}), 'DIV','foo' ); expect(() => instance.replaceState({})).toThrow(); expect(() => instance.isMounted()).toThrow(); - expect((console.error).calls.count()).toBe(2); - expect((console.error).calls.argsFor(0)[0]).toContain( + expect((console.warn).calls.count()).toBe(2); + expect((console.warn).calls.argsFor(0)[0]).toContain( 'replaceState(...) is deprecated in plain JavaScript React classes' ); - expect((console.error).calls.argsFor(1)[0]).toContain( + expect((console.warn).calls.argsFor(1)[0]).toContain( 'isMounted(...) is deprecated in plain JavaScript React classes' ); }); diff --git a/src/renderers/__tests__/ReactPerf-test.js b/src/renderers/__tests__/ReactPerf-test.js index a610e9523d497..9ba784a32fbe8 100644 --- a/src/renderers/__tests__/ReactPerf-test.js +++ b/src/renderers/__tests__/ReactPerf-test.js @@ -406,30 +406,30 @@ describeStack('ReactPerf', () => { it('warns once when using getMeasurementsSummaryMap', () => { var measurements = measure(() => {}); - spyOn(console, 'error'); + spyOn(console, 'warn'); ReactPerf.getMeasurementsSummaryMap(measurements); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( '`ReactPerf.getMeasurementsSummaryMap(...)` is deprecated. Use ' + '`ReactPerf.getWasted(...)` instead.', ); ReactPerf.getMeasurementsSummaryMap(measurements); - expectDev(console.error.calls.count()).toBe(1); + expectDev(console.warn.calls.count()).toBe(1); }); it('warns once when using printDOM', () => { var measurements = measure(() => {}); - spyOn(console, 'error'); + spyOn(console, 'warn'); ReactPerf.printDOM(measurements); - expectDev(console.error.calls.count()).toBe(1); - expectDev(console.error.calls.argsFor(0)[0]).toContain( + expectDev(console.warn.calls.count()).toBe(1); + expectDev(console.warn.calls.argsFor(0)[0]).toContain( '`ReactPerf.printDOM(...)` is deprecated. Use ' + '`ReactPerf.printOperations(...)` instead.', ); ReactPerf.printDOM(measurements); - expectDev(console.error.calls.count()).toBe(1); + expectDev(console.warn.calls.count()).toBe(1); }); it('returns isRunning state', () => { diff --git a/src/renderers/shared/ReactPerf.js b/src/renderers/shared/ReactPerf.js index d119959c551b1..17abb58095e75 100644 --- a/src/renderers/shared/ReactPerf.js +++ b/src/renderers/shared/ReactPerf.js @@ -13,7 +13,7 @@ 'use strict'; var ReactDebugTool = require('ReactDebugTool'); -var warning = require('fbjs/lib/warning'); +var lowPriorityWarning = require('lowPriorityWarning'); var alreadyWarned = false; import type {FlushHistory} from 'ReactDebugTool'; @@ -390,7 +390,7 @@ function printOperations(flushHistory?: FlushHistory) { var warnedAboutPrintDOM = false; function printDOM(measurements: FlushHistory) { - warning( + lowPriorityWarning( warnedAboutPrintDOM, '`ReactPerf.printDOM(...)` is deprecated. Use ' + '`ReactPerf.printOperations(...)` instead.', @@ -401,7 +401,7 @@ function printDOM(measurements: FlushHistory) { var warnedAboutGetMeasurementsSummaryMap = false; function getMeasurementsSummaryMap(measurements: FlushHistory) { - warning( + lowPriorityWarning( warnedAboutGetMeasurementsSummaryMap, '`ReactPerf.getMeasurementsSummaryMap(...)` is deprecated. Use ' + '`ReactPerf.getWasted(...)` instead.', diff --git a/src/shared/utils/deprecated.js b/src/shared/utils/deprecated.js index 1ed8bb2019283..81e24cfd98d5d 100644 --- a/src/shared/utils/deprecated.js +++ b/src/shared/utils/deprecated.js @@ -12,7 +12,7 @@ 'use strict'; -var warning = require('fbjs/lib/warning'); +var lowPriorityWarning = require('lowPriorityWarning'); /** * This will log a single deprecation notice per function and forward the call @@ -35,7 +35,7 @@ function deprecated( var warned = false; if (__DEV__) { var newFn = function() { - warning( + lowPriorityWarning( warned, /* eslint-disable no-useless-concat */ // Require examples in this string must be split to prevent React's diff --git a/src/shared/utils/lowPriorityWarning.js b/src/shared/utils/lowPriorityWarning.js new file mode 100644 index 0000000000000..d4deb584dccc8 --- /dev/null +++ b/src/shared/utils/lowPriorityWarning.js @@ -0,0 +1,41 @@ +/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule lowPriorityWarning + */ + +'use strict'; + +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var lowPriorityWarning = function() {}; + +if (__DEV__) { + lowPriorityWarning = function(condition, format, ...args) { + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); + if (!condition && typeof console !== 'undefined') { + console.warn(message); + } + }; +} + +module.exports = lowPriorityWarning;