diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration.js index 63a0104f0cc60..5a20146ff821e 100644 --- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration.js +++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration.js @@ -258,6 +258,45 @@ describe('ReactDOMServerHydration', () => { expect(element.firstChild.focus).not.toHaveBeenCalled(); }); + it('should warn when the style property differs', () => { + const element = document.createElement('div'); + element.innerHTML = ReactDOMServer.renderToString( +
, + ); + expect(element.firstChild.style.textDecoration).toBe('none'); + expect(element.firstChild.style.color).toBe('black'); + + expect(() => + ReactDOM.hydrate( +
, + element, + ), + ).toWarnDev( + 'Warning: Prop `style` did not match. Server: ' + + '"text-decoration:none;color:black" Client: ' + + '"text-decoration:none;color:white"', + {withoutStack: true}, + ); + }); + + it('should not warn when the style property differs on whitespace only', () => { + const element = document.createElement('div'); + element.innerHTML = ReactDOMServer.renderToString( +
, + ); + expect(element.firstChild.style.textDecoration).toBe('none'); + expect(element.firstChild.style.color).toBe('black'); + + spyOnDevAndProd(console, 'error'); + + ReactDOM.hydrate( +
, + element, + ); + + expect(console.error).not.toHaveBeenCalled(); + }); + it('should throw rendering portals on the server', () => { const div = document.createElement('div'); expect(() => { diff --git a/packages/react-dom/src/client/ReactDOMFiberComponent.js b/packages/react-dom/src/client/ReactDOMFiberComponent.js index 11d491572c1d8..5d8a9b2fb67e9 100644 --- a/packages/react-dom/src/client/ReactDOMFiberComponent.js +++ b/packages/react-dom/src/client/ReactDOMFiberComponent.js @@ -102,12 +102,24 @@ if (__DEV__) { const NORMALIZE_NEWLINES_REGEX = /\r\n?/g; const NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g; - normalizeMarkupForTextOrAttribute = function(markup: mixed): string { + normalizeMarkupForTextOrAttribute = function( + markup: mixed, + propName?: string, + ): string { const markupString = typeof markup === 'string' ? markup : '' + (markup: any); - return markupString + const markupNormalized = markupString .replace(NORMALIZE_NEWLINES_REGEX, '\n') .replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ''); + if (propName !== 'style') { + return markupNormalized; + } + // IE 11 parses & normalizes the style attribute as opposed to other + // browsers. The following normalization will still fail if the style + // attribute contains invalid CSS declarations but the majority of + // false warnings comes from spacing issues. + // See https://github.com/facebook/react/issues/11807 + return markupNormalized.replace(/\s*([:;])\s*/, '$1').replace(/;$/, ''); }; warnForTextDifference = function( @@ -141,9 +153,11 @@ if (__DEV__) { } const normalizedClientValue = normalizeMarkupForTextOrAttribute( clientValue, + propName, ); const normalizedServerValue = normalizeMarkupForTextOrAttribute( serverValue, + propName, ); if (normalizedServerValue === normalizedClientValue) { return; diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index ea7d1c4e07de1..7c479ad12ca2c 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -4,29 +4,29 @@ "filename": "react.development.js", "bundleType": "UMD_DEV", "packageName": "react", - "size": 59086, - "gzip": 16296 + "size": 61012, + "gzip": 17111 }, { "filename": "react.production.min.js", "bundleType": "UMD_PROD", "packageName": "react", - "size": 7217, - "gzip": 3050 + "size": 7289, + "gzip": 3104 }, { "filename": "react.development.js", "bundleType": "NODE_DEV", "packageName": "react", - "size": 49501, - "gzip": 13887 + "size": 55065, + "gzip": 15236 }, { "filename": "react.production.min.js", "bundleType": "NODE_PROD", "packageName": "react", - "size": 5724, - "gzip": 2481 + "size": 6269, + "gzip": 2699 }, { "filename": "React-dev.js", @@ -46,29 +46,29 @@ "filename": "react-dom.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 641505, - "gzip": 149286 + "size": 676602, + "gzip": 158829 }, { "filename": "react-dom.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 96507, - "gzip": 31258 + "size": 98642, + "gzip": 32425 }, { "filename": "react-dom.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 625496, - "gzip": 145193 + "size": 672601, + "gzip": 157672 }, { "filename": "react-dom.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 94969, - "gzip": 30225 + "size": 98585, + "gzip": 32159 }, { "filename": "ReactDOM-dev.js", @@ -88,29 +88,29 @@ "filename": "react-dom-test-utils.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 46355, - "gzip": 12768 + "size": 46151, + "gzip": 12521 }, { "filename": "react-dom-test-utils.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 10653, - "gzip": 3918 + "size": 10902, + "gzip": 4030 }, { "filename": "react-dom-test-utils.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 41092, - "gzip": 11309 + "size": 45865, + "gzip": 12455 }, { "filename": "react-dom-test-utils.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 9913, - "gzip": 3696 + "size": 10692, + "gzip": 3968 }, { "filename": "ReactTestUtils-dev.js", @@ -123,29 +123,29 @@ "filename": "react-dom-unstable-native-dependencies.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 62921, - "gzip": 16559 + "size": 61704, + "gzip": 16136 }, { "filename": "react-dom-unstable-native-dependencies.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 11622, - "gzip": 4007 + "size": 11488, + "gzip": 3962 }, { "filename": "react-dom-unstable-native-dependencies.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 58483, - "gzip": 15262 + "size": 61368, + "gzip": 16003 }, { "filename": "react-dom-unstable-native-dependencies.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 10939, - "gzip": 3744 + "size": 11233, + "gzip": 3871 }, { "filename": "ReactDOMUnstableNativeDependencies-dev.js", @@ -165,29 +165,29 @@ "filename": "react-dom-server.browser.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 105006, - "gzip": 27524 + "size": 106513, + "gzip": 28495 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 15463, - "gzip": 5917 + "size": 15697, + "gzip": 6004 }, { "filename": "react-dom-server.browser.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 94052, - "gzip": 25217 + "size": 102551, + "gzip": 27495 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 14810, - "gzip": 5665 + "size": 15597, + "gzip": 5948 }, { "filename": "ReactDOMServer-dev.js", @@ -207,43 +207,43 @@ "filename": "react-dom-server.node.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 96020, - "gzip": 25767 + "size": 104519, + "gzip": 28035 }, { "filename": "react-dom-server.node.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 15634, - "gzip": 5964 + "size": 16422, + "gzip": 6261 }, { "filename": "react-art.development.js", "bundleType": "UMD_DEV", "packageName": "react-art", - "size": 417844, - "gzip": 93214 + "size": 463703, + "gzip": 104864 }, { "filename": "react-art.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-art", - "size": 83064, - "gzip": 25615 + "size": 89418, + "gzip": 27718 }, { "filename": "react-art.development.js", "bundleType": "NODE_DEV", "packageName": "react-art", - "size": 341917, - "gzip": 73846 + "size": 394625, + "gzip": 87367 }, { "filename": "react-art.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-art", - "size": 46568, - "gzip": 14504 + "size": 53571, + "gzip": 16856 }, { "filename": "ReactART-dev.js", @@ -291,29 +291,29 @@ "filename": "react-test-renderer.development.js", "bundleType": "UMD_DEV", "packageName": "react-test-renderer", - "size": 349236, - "gzip": 75574 + "size": 391223, + "gzip": 85588 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-test-renderer", - "size": 47024, - "gzip": 14562 + "size": 52905, + "gzip": 16287 }, { "filename": "react-test-renderer.development.js", "bundleType": "NODE_DEV", "packageName": "react-test-renderer", - "size": 339847, - "gzip": 72777 + "size": 387215, + "gzip": 84593 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-test-renderer", - "size": 46110, - "gzip": 14094 + "size": 52562, + "gzip": 16097 }, { "filename": "ReactTestRenderer-dev.js", @@ -326,29 +326,29 @@ "filename": "react-test-renderer-shallow.development.js", "bundleType": "UMD_DEV", "packageName": "react-test-renderer", - "size": 24945, - "gzip": 6660 + "size": 24872, + "gzip": 6771 }, { "filename": "react-test-renderer-shallow.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-test-renderer", - "size": 7320, - "gzip": 2398 + "size": 7342, + "gzip": 2403 }, { "filename": "react-test-renderer-shallow.development.js", "bundleType": "NODE_DEV", "packageName": "react-test-renderer", - "size": 14751, - "gzip": 3694 + "size": 19948, + "gzip": 5555 }, { "filename": "react-test-renderer-shallow.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-test-renderer", - "size": 7363, - "gzip": 2403 + "size": 8058, + "gzip": 2677 }, { "filename": "ReactShallowRenderer-dev.js", @@ -361,57 +361,57 @@ "filename": "react-noop-renderer.development.js", "bundleType": "NODE_DEV", "packageName": "react-noop-renderer", - "size": 18358, - "gzip": 4804 + "size": 23906, + "gzip": 5456 }, { "filename": "react-noop-renderer.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-noop-renderer", - "size": 6829, - "gzip": 2631 + "size": 8960, + "gzip": 3109 }, { "filename": "react-reconciler.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 331893, - "gzip": 70268 + "size": 375214, + "gzip": 81184 }, { "filename": "react-reconciler.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 46230, - "gzip": 13812 + "size": 51017, + "gzip": 15460 }, { "filename": "react-reconciler-persistent.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 330477, - "gzip": 69672 + "size": 373748, + "gzip": 80596 }, { "filename": "react-reconciler-persistent.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 46241, - "gzip": 13818 + "size": 51028, + "gzip": 15465 }, { "filename": "react-reconciler-reflection.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 11847, - "gzip": 3642 + "size": 15113, + "gzip": 4726 }, { "filename": "react-reconciler-reflection.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 2312, - "gzip": 1027 + "size": 2616, + "gzip": 1160 }, { "filename": "react-call-return.development.js", @@ -431,29 +431,29 @@ "filename": "react-is.development.js", "bundleType": "UMD_DEV", "packageName": "react-is", - "size": 4785, - "gzip": 1323 + "size": 4840, + "gzip": 1337 }, { "filename": "react-is.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-is", - "size": 1933, - "gzip": 787 + "size": 1973, + "gzip": 802 }, { "filename": "react-is.development.js", "bundleType": "NODE_DEV", "packageName": "react-is", - "size": 4596, - "gzip": 1264 + "size": 4651, + "gzip": 1279 }, { "filename": "react-is.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-is", - "size": 1881, - "gzip": 719 + "size": 1922, + "gzip": 735 }, { "filename": "ReactIs-dev.js", @@ -473,281 +473,358 @@ "filename": "simple-cache-provider.development.js", "bundleType": "NODE_DEV", "packageName": "simple-cache-provider", - "size": 7654, - "gzip": 2412 + "size": 9103, + "gzip": 2933 }, { "filename": "simple-cache-provider.production.min.js", "bundleType": "NODE_PROD", "packageName": "simple-cache-provider", - "size": 1667, - "gzip": 827 + "size": 1675, + "gzip": 833 }, { "filename": "create-subscription.development.js", "bundleType": "NODE_DEV", "packageName": "create-subscription", - "size": 5636, - "gzip": 1973 + "size": 8190, + "gzip": 2840 }, { "filename": "create-subscription.production.min.js", "bundleType": "NODE_PROD", "packageName": "create-subscription", - "size": 2591, - "gzip": 1233 + "size": 2888, + "gzip": 1353 }, { "filename": "React-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react", - "size": 49728, - "gzip": 13583 + "size": 52612, + "gzip": 14562 }, { "filename": "React-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react", - "size": 13708, - "gzip": 3835 + "size": 14405, + "gzip": 4057 }, { "filename": "ReactDOM-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 634902, - "gzip": 144512 + "size": 680176, + "gzip": 155746 }, { "filename": "ReactDOM-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 275897, - "gzip": 51771 + "size": 295978, + "gzip": 55166 }, { "filename": "ReactTestUtils-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 42513, - "gzip": 11507 + "size": 42883, + "gzip": 11479 }, { "filename": "ReactDOMUnstableNativeDependencies-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 58699, - "gzip": 15042 + "size": 59010, + "gzip": 14927 }, { "filename": "ReactDOMUnstableNativeDependencies-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 26877, - "gzip": 5467 + "size": 27322, + "gzip": 5487 }, { "filename": "ReactDOMServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 97859, - "gzip": 25094 + "size": 103677, + "gzip": 27148 }, { "filename": "ReactDOMServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 32295, - "gzip": 7922 + "size": 33849, + "gzip": 8196 }, { "filename": "ReactART-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-art", - "size": 334032, - "gzip": 69646 + "size": 384806, + "gzip": 82049 }, { "filename": "ReactART-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-art", - "size": 145574, - "gzip": 24830 + "size": 164689, + "gzip": 28152 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 468596, - "gzip": 102411 + "size": 509169, + "gzip": 112572 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 210858, - "gzip": 36787 + "size": 219840, + "gzip": 38359 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 468299, - "gzip": 102347 + "size": 508896, + "gzip": 112508 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 198778, - "gzip": 34759 + "size": 209417, + "gzip": 36672 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 459344, - "gzip": 100124 + "size": 499117, + "gzip": 110102 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 190842, - "gzip": 33372 + "size": 201745, + "gzip": 35143 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 459380, - "gzip": 100141 + "size": 499153, + "gzip": 110118 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 190878, - "gzip": 33392 + "size": 201781, + "gzip": 35159 }, { "filename": "ReactTestRenderer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-test-renderer", - "size": 345831, - "gzip": 72349 + "size": 392462, + "gzip": 83621 }, { "filename": "ReactShallowRenderer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-test-renderer", - "size": 15507, - "gzip": 3819 + "size": 18218, + "gzip": 4803 }, { "filename": "ReactIs-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-is", - "size": 4669, - "gzip": 1292 + "size": 4728, + "gzip": 1301 }, { "filename": "ReactIs-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-is", - "size": 3756, - "gzip": 999 + "size": 3811, + "gzip": 1012 }, { "filename": "react-scheduler.development.js", "bundleType": "UMD_DEV", "packageName": "react-scheduler", - "size": 19628, - "gzip": 5881 + "size": 15772, + "gzip": 4758 }, { "filename": "react-scheduler.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-scheduler", - "size": 3233, - "gzip": 1562 + "size": 2792, + "gzip": 1291 }, { "filename": "react-scheduler.development.js", "bundleType": "NODE_DEV", "packageName": "react-scheduler", - "size": 14449, - "gzip": 4354 + "size": 15576, + "gzip": 4717 }, { "filename": "react-scheduler.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-scheduler", - "size": 2825, - "gzip": 1387 + "size": 2709, + "gzip": 1235 }, { "filename": "SimpleCacheProvider-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "simple-cache-provider", - "size": 8054, - "gzip": 2450 + "size": 8106, + "gzip": 2454 }, { "filename": "SimpleCacheProvider-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "simple-cache-provider", - "size": 3714, - "gzip": 1127 + "size": 3734, + "gzip": 1137 }, { "filename": "react-noop-renderer-persistent.development.js", "bundleType": "NODE_DEV", "packageName": "react-noop-renderer", - "size": 18487, - "gzip": 4818 + "size": 24025, + "gzip": 5470 }, { "filename": "react-noop-renderer-persistent.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-noop-renderer", - "size": 6851, - "gzip": 2637 + "size": 8982, + "gzip": 3115 }, { "filename": "react-dom.profiling.min.js", "bundleType": "NODE_PROFILING", "packageName": "react-dom", - "size": 95896, - "gzip": 30574 + "size": 101535, + "gzip": 32728 }, { "filename": "ReactNativeRenderer-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 201375, - "gzip": 35312 + "size": 212915, + "gzip": 37354 }, { "filename": "ReactFabric-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 193150, - "gzip": 33867 + "size": 204820, + "gzip": 35730 }, { "filename": "ReactScheduler-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-scheduler", - "size": 14452, - "gzip": 4364 + "size": 15788, + "gzip": 4747 }, { "filename": "ReactScheduler-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-scheduler", - "size": 7800, - "gzip": 2108 + "size": 7759, + "gzip": 1939 + }, + { + "filename": "ReactDOM-profiling.js", + "bundleType": "FB_WWW_PROFILING", + "packageName": "react-dom", + "size": 301510, + "gzip": 56533 + }, + { + "filename": "ReactNativeRenderer-profiling.js", + "bundleType": "RN_FB_PROFILING", + "packageName": "react-native-renderer", + "size": 223321, + "gzip": 39028 + }, + { + "filename": "ReactFabric-profiling.js", + "bundleType": "RN_FB_PROFILING", + "packageName": "react-native-renderer", + "size": 204779, + "gzip": 35710 + }, + { + "filename": "interaction-tracking.development.js", + "bundleType": "UMD_DEV", + "packageName": "interaction-tracking", + "size": 7342, + "gzip": 2227 + }, + { + "filename": "interaction-tracking.production.min.js", + "bundleType": "UMD_PROD", + "packageName": "interaction-tracking", + "size": 739, + "gzip": 444 + }, + { + "filename": "interaction-tracking.development.js", + "bundleType": "NODE_DEV", + "packageName": "interaction-tracking", + "size": 7141, + "gzip": 2152 + }, + { + "filename": "interaction-tracking.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "interaction-tracking", + "size": 597, + "gzip": 360 + }, + { + "filename": "interaction-tracking-subscriptions.development.js", + "bundleType": "UMD_DEV", + "packageName": "interaction-tracking", + "size": 5287, + "gzip": 1488 + }, + { + "filename": "interaction-tracking-subscriptions.production.min.js", + "bundleType": "UMD_PROD", + "packageName": "interaction-tracking", + "size": 673, + "gzip": 396 + }, + { + "filename": "interaction-tracking-subscriptions.development.js", + "bundleType": "NODE_DEV", + "packageName": "interaction-tracking", + "size": 5029, + "gzip": 1390 + }, + { + "filename": "interaction-tracking-subscriptions.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "interaction-tracking", + "size": 439, + "gzip": 302 } ] } \ No newline at end of file