@samitouri / QOS-React / commits / 411e04bd71

Add ReactDOMNodeStream, adding streaming rendering. (#10024)

* Add ReactDOMNodeStream, adding ability to stream generated HTML. * Forgot to rename a documentation page. * Tests are passing locally but failing on CI; attempt to fix that with this tweak. * Adding some debugging info to try to track down CI problem. * More debugging of CI. Yay for printf debugging. * More printf debugging of CI to figure out what is going on with includes during tests. * I made a truly stupid error with my printf debugging statements for CI. Fixing that. * And another dumb copy and paste typo. * The node-stream.js stub for tests wasn't being added because of .gitignore. * Fix for code review coment https://github.com/facebook/react/pull/10024#discussion_r123606138 . Thanks to @razh for helping me out. * Removing all the console.logs I put in to debug the build problems on the CI server. * Fix for code review coment https://github.com/facebook/react/pull/10024#discussion_r123628227 . Thanks to @aweary for the suggestion. * Response to code review comment https://github.com/facebook/react/pull/10024#discussion_r123649131 . Thanks, @gaearon. * Responding to code comments https://github.com/facebook/react/pull/10024#pullrequestreview-46104491 , https://github.com/facebook/react/pull/10024#pullrequestreview-46104616 , and https://github.com/facebook/react/pull/10024#pullrequestreview-46104822 . Thanks to @sebmarkbage for the help. * Attempt to tweak spacing to see if it makes the prettier build step happy. * Found a prettier bug that wasn't being reported by npm run prettier for some reason. * Fixed a small prettier issue

Sasha Aickin committed Jun 24, 2017 at 22:31 UTC 411e04bd71715298de564a24dbf0304e17471ce0
14 files changed +548 -125
docs/_data/nav_docs.yml
+2
@@ -63,6 +63,8 @@
63 title: ReactDOM
64 - id: react-dom-server
65 title: ReactDOMServer
66 + - id: react-dom-node-stream
67 + title: ReactDOMNodeStream
68 - id: dom-elements
69 title: DOM Elements
70 - id: events
docs/docs/reference-react-dom-node-stream.md new
+42
@@ -0,0 +1,42 @@
1 +---
2 +id: react-dom-node-stream
3 +title: ReactDOMNodeStream
4 +layout: docs
5 +category: Reference
6 +permalink: docs/react-dom-node-stream.html
7 +---
8 +
9 +If you use ES6 with npm, you can write `import ReactDOMNodeStream from 'react-dom/node-stream'`. If you use ES5 with npm, you can write `var ReactDOMNodeStream = require('react-dom/node-stream')`.
10 +
11 +Unlike other packages in React, `ReactDOMNodeStream` depends on a package (`stream`) that is available in Node.js but not in the browser. For this reason, there is no `<script>` tag version of `ReactDOMNodeStream`; it is only provided as a Node.js module.
12 +
13 +## Overview
14 +
15 +The `ReactDOMNodeStream` object allows you to render your components in Node.js and stream the resulting markup.
16 +
17 + - [`renderToStream()`](#rendertostream)
18 + - [`renderToStaticStream()`](#rendertostaticstream)
19 +
20 +* * *
21 +
22 +## Reference
23 +
24 +### `renderToStream()`
25 +
26 +```javascript
27 +ReactDOMNodeStream.renderToStream(element)
28 +```
29 +
30 +Render a React element to its initial HTML. This should only be used in Node.js; it will not work in the browser, since the browser does not support Node.js streams. React will return a [Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) that outputs an HTML string. The HTML output by this stream will be exactly equal to what [`ReactDOMServer.renderToString`](https://facebook.github.io/react/docs/react-dom-server.html#rendertostring) would return. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes.
31 +
32 +If you call [`ReactDOM.render()`](/react/docs/react-dom.html#render) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.
33 +
34 +* * *
35 +
36 +### `renderToStaticStream()`
37 +
38 +```javascript
39 +ReactDOMNodeStream.renderToStaticStream(element)
40 +```
41 +
42 +Similar to [`renderToStream`](#rendertostream), except this doesn't create extra DOM attributes such as `data-reactid`, that React uses internally. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save lots of bytes.
packages/react-dom/node-stream.js new
+7
@@ -0,0 +1,7 @@
1 +'use strict';
2 +
3 +if (process.env.NODE_ENV === 'production') {
4 + module.exports = require('./cjs/react-dom-node-stream.production.min.js');
5 +} else {
6 + module.exports = require('./cjs/react-dom-node-stream.development.js');
7 +}
scripts/fiber/tests-passing.txt
+117
@@ -882,246 +882,327 @@ src/renderers/dom/shared/__tests__/ReactDOMSVG-test.js
882
883 src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
884 * renders a blank div with server string render
885 +* renders a blank div with server stream render
886 * renders a blank div with clean client render
887 * renders a blank div with client render on top of good server markup
888 * renders a div with inline styles with server string render
889 +* renders a div with inline styles with server stream render
890 * renders a div with inline styles with clean client render
891 * renders a div with inline styles with client render on top of good server markup
892 * renders a self-closing tag with server string render
893 +* renders a self-closing tag with server stream render
894 * renders a self-closing tag with clean client render
895 * renders a self-closing tag with client render on top of good server markup
896 * renders a self-closing tag as a child with server string render
897 +* renders a self-closing tag as a child with server stream render
898 * renders a self-closing tag as a child with clean client render
899 * renders a self-closing tag as a child with client render on top of good server markup
900 * renders simple numbers with server string render
901 +* renders simple numbers with server stream render
902 * renders simple numbers with clean client render
903 * renders simple numbers with client render on top of good server markup
904 * renders simple strings with server string render
905 +* renders simple strings with server stream render
906 * renders simple strings with clean client render
907 * renders simple strings with client render on top of good server markup
908 * renders string prop with true value with server string render
909 +* renders string prop with true value with server stream render
910 * renders string prop with true value with clean client render
911 * renders string prop with true value with client render on top of good server markup
912 * renders string prop with false value with server string render
913 +* renders string prop with false value with server stream render
914 * renders string prop with false value with clean client render
915 * renders string prop with false value with client render on top of good server markup
916 * renders boolean prop with true value with server string render
917 +* renders boolean prop with true value with server stream render
918 * renders boolean prop with true value with clean client render
919 * renders boolean prop with true value with client render on top of good server markup
920 * renders boolean prop with false value with server string render
921 +* renders boolean prop with false value with server stream render
922 * renders boolean prop with false value with clean client render
923 * renders boolean prop with false value with client render on top of good server markup
924 * renders boolean prop with self value with server string render
925 +* renders boolean prop with self value with server stream render
926 * renders boolean prop with self value with clean client render
927 * renders boolean prop with self value with client render on top of good server markup
928 * renders boolean prop with "" value with server string render
929 +* renders boolean prop with "" value with server stream render
930 * renders boolean prop with "" value with clean client render
931 * renders boolean prop with "" value with client render on top of good server markup
932 * renders boolean prop with string value with server string render
933 +* renders boolean prop with string value with server stream render
934 * renders boolean prop with string value with clean client render
935 * renders boolean prop with string value with client render on top of good server markup
936 * renders boolean prop with array value with server string render
937 +* renders boolean prop with array value with server stream render
938 * renders boolean prop with array value with clean client render
939 * renders boolean prop with array value with client render on top of good server markup
940 * renders boolean prop with object value with server string render
941 +* renders boolean prop with object value with server stream render
942 * renders boolean prop with object value with clean client render
943 * renders boolean prop with object value with client render on top of good server markup
944 * renders boolean prop with non-zero number value with server string render
945 +* renders boolean prop with non-zero number value with server stream render
946 * renders boolean prop with non-zero number value with clean client render
947 * renders boolean prop with non-zero number value with client render on top of good server markup
948 * renders boolean prop with zero value with server string render
949 +* renders boolean prop with zero value with server stream render
950 * renders boolean prop with zero value with clean client render
951 * renders boolean prop with zero value with client render on top of good server markup
952 * renders download prop with true value with server string render
953 +* renders download prop with true value with server stream render
954 * renders download prop with true value with clean client render
955 * renders download prop with true value with client render on top of good server markup
956 * renders download prop with false value with server string render
957 +* renders download prop with false value with server stream render
958 * renders download prop with false value with clean client render
959 * renders download prop with false value with client render on top of good server markup
960 * renders download prop with string value with server string render
961 +* renders download prop with string value with server stream render
962 * renders download prop with string value with clean client render
963 * renders download prop with string value with client render on top of good server markup
964 * renders download prop with string "true" value with server string render
965 +* renders download prop with string "true" value with server stream render
966 * renders download prop with string "true" value with clean client render
967 * renders download prop with string "true" value with client render on top of good server markup
968 * renders className prop with string value with server string render
969 +* renders className prop with string value with server stream render
970 * renders className prop with string value with clean client render
971 * renders className prop with string value with client render on top of good server markup
972 * renders className prop with empty string value with server string render
973 +* renders className prop with empty string value with server stream render
974 * renders className prop with empty string value with clean client render
975 * renders className prop with empty string value with client render on top of good server markup
976 * renders className prop with true value with server string render
977 +* renders className prop with true value with server stream render
978 * renders className prop with true value with clean client render
979 * renders className prop with true value with client render on top of good server markup
980 * renders className prop with false value with server string render
981 +* renders className prop with false value with server stream render
982 * renders className prop with false value with clean client render
983 * renders className prop with false value with client render on top of good server markup
984 * renders htmlFor with string value with server string render
985 +* renders htmlFor with string value with server stream render
986 * renders htmlFor with string value with clean client render
987 * renders htmlFor with string value with client render on top of good server markup
988 * renders htmlFor with an empty string with server string render
989 +* renders htmlFor with an empty string with server stream render
990 * renders htmlFor with an empty string with clean client render
991 * renders htmlFor with an empty string with client render on top of good server markup
992 * renders className prop with true value with server string render
993 +* renders className prop with true value with server stream render
994 * renders className prop with true value with clean client render
995 * renders className prop with true value with client render on top of good server markup
996 * renders className prop with false value with server string render
997 +* renders className prop with false value with server stream render
998 * renders className prop with false value with clean client render
999 * renders className prop with false value with client render on top of good server markup
1000 * renders no ref attribute with server string render
1001 +* renders no ref attribute with server stream render
1002 * renders no ref attribute with clean client render
1003 * renders no ref attribute with client render on top of good server markup
1004 * renders no children attribute with server string render
1005 +* renders no children attribute with server stream render
1006 * renders no children attribute with clean client render
1007 * renders no children attribute with client render on top of good server markup
1008 * renders no key attribute with server string render
1009 +* renders no key attribute with server stream render
1010 * renders no key attribute with clean client render
1011 * renders no key attribute with client render on top of good server markup
1012 * renders no dangerouslySetInnerHTML attribute with server string render
1013 +* renders no dangerouslySetInnerHTML attribute with server stream render
1014 * renders no dangerouslySetInnerHTML attribute with clean client render
1015 * renders no dangerouslySetInnerHTML attribute with client render on top of good server markup
1016 * renders no unknown attributes with server string render
1017 +* renders no unknown attributes with server stream render
1018 * renders no unknown attributes with clean client render
1019 * renders no unknown attributes with client render on top of good server markup
1020 * renders unknown data- attributes with server string render
1021 +* renders unknown data- attributes with server stream render
1022 * renders unknown data- attributes with clean client render
1023 * renders unknown data- attributes with client render on top of good server markup
1024 * renders no unknown attributes for non-standard elements with server string render
1025 +* renders no unknown attributes for non-standard elements with server stream render
1026 * renders no unknown attributes for non-standard elements with clean client render
1027 * renders no unknown attributes for non-standard elements with client render on top of good server markup
1028 * renders unknown attributes for custom elements with server string render
1029 +* renders unknown attributes for custom elements with server stream render
1030 * renders unknown attributes for custom elements with clean client render
1031 * renders unknown attributes for custom elements with client render on top of good server markup
1032 * renders unknown attributes for custom elements using is with server string render
1033 +* renders unknown attributes for custom elements using is with server stream render
1034 * renders unknown attributes for custom elements using is with clean client render
1035 * renders unknown attributes for custom elements using is with client render on top of good server markup
1036 * renders no HTML events with server string render
1037 +* renders no HTML events with server stream render
1038 * renders no HTML events with clean client render
1039 * renders no HTML events with client render on top of good server markup
1040 * renders a div with text with server string render
1041 +* renders a div with text with server stream render
1042 * renders a div with text with clean client render
1043 * renders a div with text with client render on top of good server markup
1044 * renders a div with text with flanking whitespace with server string render
1045 +* renders a div with text with flanking whitespace with server stream render
1046 * renders a div with text with flanking whitespace with clean client render
1047 * renders a div with text with flanking whitespace with client render on top of good server markup
1048 * renders a div with an empty text child with server string render
1049 +* renders a div with an empty text child with server stream render
1050 * renders a div with an empty text child with clean client render
1051 * renders a div with an empty text child with client render on top of good server markup
1052 * renders a div with multiple empty text children with server string render
1053 +* renders a div with multiple empty text children with server stream render
1054 * renders a div with multiple empty text children with clean client render
1055 * renders a div with multiple empty text children with client render on top of good server markup
1056 * renders a div with multiple whitespace children with server string render
1057 +* renders a div with multiple whitespace children with server stream render
1058 * renders a div with multiple whitespace children with clean client render
1059 * renders a div with multiple whitespace children with client render on top of good server markup
1060 * renders a div with text sibling to a node with server string render
1061 +* renders a div with text sibling to a node with server stream render
1062 * renders a div with text sibling to a node with clean client render
1063 * renders a div with text sibling to a node with client render on top of good server markup
1064 * renders a non-standard element with text with server string render
1065 +* renders a non-standard element with text with server stream render
1066 * renders a non-standard element with text with clean client render
1067 * renders a non-standard element with text with client render on top of good server markup
1068 * renders a custom element with text with server string render
1069 +* renders a custom element with text with server stream render
1070 * renders a custom element with text with clean client render
1071 * renders a custom element with text with client render on top of good server markup
1072 * renders a leading blank child with a text sibling with server string render
1073 +* renders a leading blank child with a text sibling with server stream render
1074 * renders a leading blank child with a text sibling with clean client render
1075 * renders a leading blank child with a text sibling with client render on top of good server markup
1076 * renders a trailing blank child with a text sibling with server string render
1077 +* renders a trailing blank child with a text sibling with server stream render
1078 * renders a trailing blank child with a text sibling with clean client render
1079 * renders a trailing blank child with a text sibling with client render on top of good server markup
1080 * renders an element with two text children with server string render
1081 +* renders an element with two text children with server stream render
1082 * renders an element with two text children with clean client render
1083 * renders an element with two text children with client render on top of good server markup
1084 * renders a number as single child with server string render
1085 +* renders a number as single child with server stream render
1086 * renders a number as single child with clean client render
1087 * renders a number as single child with client render on top of good server markup
1088 * renders zero as single child with server string render
1089 +* renders zero as single child with server stream render
1090 * renders zero as single child with clean client render
1091 * renders zero as single child with client render on top of good server markup
1092 * renders an element with number and text children with server string render
1093 +* renders an element with number and text children with server stream render
1094 * renders an element with number and text children with clean client render
1095 * renders an element with number and text children with client render on top of good server markup
1096 * renders null single child as blank with server string render
1097 +* renders null single child as blank with server stream render
1098 * renders null single child as blank with clean client render
1099 * renders null single child as blank with client render on top of good server markup
1100 * renders false single child as blank with server string render
1101 +* renders false single child as blank with server stream render
1102 * renders false single child as blank with clean client render
1103 * renders false single child as blank with client render on top of good server markup
1104 * renders undefined single child as blank with server string render
1105 +* renders undefined single child as blank with server stream render
1106 * renders undefined single child as blank with clean client render
1107 * renders undefined single child as blank with client render on top of good server markup
1108 * renders a null component children as empty with server string render
1109 +* renders a null component children as empty with server stream render
1110 * renders a null component children as empty with clean client render
1111 * renders a null component children as empty with client render on top of good server markup
1112 * renders null children as blank with server string render
1113 +* renders null children as blank with server stream render
1114 * renders null children as blank with clean client render
1115 * renders null children as blank with client render on top of good server markup
1116 * renders false children as blank with server string render
1117 +* renders false children as blank with server stream render
1118 * renders false children as blank with clean client render
1119 * renders false children as blank with client render on top of good server markup
1120 * renders null and false children together as blank with server string render
1121 +* renders null and false children together as blank with server stream render
1122 * renders null and false children together as blank with clean client render
1123 * renders null and false children together as blank with client render on top of good server markup
1124 * renders only null and false children as blank with server string render
1125 +* renders only null and false children as blank with server stream render
1126 * renders only null and false children as blank with clean client render
1127 * renders only null and false children as blank with client render on top of good server markup
1128 * renders an svg element with server string render
1129 +* renders an svg element with server stream render
1130 * renders an svg element with clean client render
1131 * renders an svg element with client render on top of good server markup
1132 * renders svg element with an xlink with server string render
1133 +* renders svg element with an xlink with server stream render
1134 * renders svg element with an xlink with clean client render
1135 * renders svg element with an xlink with client render on top of good server markup
1136 * renders a math element with server string render
1137 +* renders a math element with server stream render
1138 * renders a math element with clean client render
1139 * renders a math element with client render on top of good server markup
1140 * renders an img with server string render
1141 +* renders an img with server stream render
1142 * renders an img with clean client render
1143 * renders an img with client render on top of good server markup
1144 * renders a button with server string render
1145 +* renders a button with server stream render
1146 * renders a button with clean client render
1147 * renders a button with client render on top of good server markup
1148 * renders a div with dangerouslySetInnerHTML with server string render
1149 +* renders a div with dangerouslySetInnerHTML with server stream render
1150 * renders a div with dangerouslySetInnerHTML with clean client render
1151 * renders a div with dangerouslySetInnerHTML with client render on top of good server markup
1152 * renders a newline-eating tag with content not starting with \n with server string render
1153 +* renders a newline-eating tag with content not starting with \n with server stream render
1154 * renders a newline-eating tag with content not starting with \n with clean client render
1155 * renders a newline-eating tag with content not starting with \n with client render on top of good server markup
1156 * renders a newline-eating tag with content starting with \n with server string render
1157 +* renders a newline-eating tag with content starting with \n with server stream render
1158 * renders a newline-eating tag with content starting with \n with clean client render
1159 * renders a newline-eating tag with content starting with \n with client render on top of good server markup
1160 * renders a normal tag with content starting with \n with server string render
1161 +* renders a normal tag with content starting with \n with server stream render
1162 * renders a normal tag with content starting with \n with clean client render
1163 * renders a normal tag with content starting with \n with client render on top of good server markup
1164 * renders stateless components with server string render
1165 +* renders stateless components with server stream render
1166 * renders stateless components with clean client render
1167 * renders stateless components with client render on top of good server markup
1168 * renders ES6 class components with server string render
1169 +* renders ES6 class components with server stream render
1170 * renders ES6 class components with clean client render
1171 * renders ES6 class components with client render on top of good server markup
1172 * renders factory components with server string render
1173 +* renders factory components with server stream render
1174 * renders factory components with clean client render
1175 * renders factory components with client render on top of good server markup
1176 * renders single child hierarchies of components with server string render
1177 +* renders single child hierarchies of components with server stream render
1178 * renders single child hierarchies of components with clean client render
1179 * renders single child hierarchies of components with client render on top of good server markup
1180 * renders multi-child hierarchies of components with server string render
1181 +* renders multi-child hierarchies of components with server stream render
1182 * renders multi-child hierarchies of components with clean client render
1183 * renders multi-child hierarchies of components with client render on top of good server markup
1184 * renders a div with a child with server string render
1185 +* renders a div with a child with server stream render
1186 * renders a div with a child with clean client render
1187 * renders a div with a child with client render on top of good server markup
1188 * renders a div with multiple children with server string render
1189 +* renders a div with multiple children with server stream render
1190 * renders a div with multiple children with clean client render
1191 * renders a div with multiple children with client render on top of good server markup
1192 * renders a div with multiple children separated by whitespace with server string render
1193 +* renders a div with multiple children separated by whitespace with server stream render
1194 * renders a div with multiple children separated by whitespace with clean client render
1195 * renders a div with multiple children separated by whitespace with client render on top of good server markup
1196 * renders a div with a single child surrounded by whitespace with server string render
1197 +* renders a div with a single child surrounded by whitespace with server stream render
1198 * renders a div with a single child surrounded by whitespace with clean client render
1199 * renders a div with a single child surrounded by whitespace with client render on top of good server markup
1200 * renders >,<, and & as single child with server string render
1201 +* renders >,<, and & as single child with server stream render
1202 * renders >,<, and & as single child with clean client render
1203 * renders >,<, and & as single child with client render on top of good server markup
1204 * renders >,<, and & as multiple children with server string render
1205 +* renders >,<, and & as multiple children with server stream render
1206 * renders >,<, and & as multiple children with clean client render
1207 * renders >,<, and & as multiple children with client render on top of good server markup
1208 * throws when rendering a string component with server string render
@@ -1143,81 +1224,107 @@ src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
1224 * throws when rendering string with clean client render
1225 * throws when rendering string with client render on top of bad server markup
1226 * renders an input with a value and an onChange with server string render
1227 +* renders an input with a value and an onChange with server stream render
1228 * renders an input with a value and an onChange with clean client render
1229 * renders an input with a value and an onChange with client render on top of good server markup
1230 * renders an input with a value and readOnly with server string render
1231 +* renders an input with a value and readOnly with server stream render
1232 * renders an input with a value and readOnly with clean client render
1233 * renders an input with a value and readOnly with client render on top of good server markup
1234 * renders an input with a value and no onChange/readOnly with server string render
1235 +* renders an input with a value and no onChange/readOnly with server stream render
1236 * renders an input with a value and no onChange/readOnly with clean client render
1237 * renders an input with a value and no onChange/readOnly with client render on top of good server markup
1238 * renders an input with a defaultValue with server string render
1239 +* renders an input with a defaultValue with server stream render
1240 * renders an input with a defaultValue with clean client render
1241 * renders an input with a defaultValue with client render on top of good server markup
1242 * renders an input value overriding defaultValue with server string render
1243 +* renders an input value overriding defaultValue with server stream render
1244 * renders an input value overriding defaultValue with clean client render
1245 * renders an input value overriding defaultValue with client render on top of good server markup
1246 * renders an input value overriding defaultValue no matter the prop order with server string render
1247 +* renders an input value overriding defaultValue no matter the prop order with server stream render
1248 * renders an input value overriding defaultValue no matter the prop order with clean client render
1249 * renders an input value overriding defaultValue no matter the prop order with client render on top of good server markup
1250 * renders a checkbox that is checked with an onChange with server string render
1251 +* renders a checkbox that is checked with an onChange with server stream render
1252 * renders a checkbox that is checked with an onChange with clean client render
1253 * renders a checkbox that is checked with an onChange with client render on top of good server markup
1254 * renders a checkbox that is checked with readOnly with server string render
1255 +* renders a checkbox that is checked with readOnly with server stream render
1256 * renders a checkbox that is checked with readOnly with clean client render
1257 * renders a checkbox that is checked with readOnly with client render on top of good server markup
1258 * renders a checkbox that is checked and no onChange/readOnly with server string render
1259 +* renders a checkbox that is checked and no onChange/readOnly with server stream render
1260 * renders a checkbox that is checked and no onChange/readOnly with clean client render
1261 * renders a checkbox that is checked and no onChange/readOnly with client render on top of good server markup
1262 * renders a checkbox with defaultChecked with server string render
1263 +* renders a checkbox with defaultChecked with server stream render
1264 * renders a checkbox with defaultChecked with clean client render
1265 * renders a checkbox with defaultChecked with client render on top of good server markup
1266 * renders a checkbox checked overriding defaultChecked with server string render
1267 +* renders a checkbox checked overriding defaultChecked with server stream render
1268 * renders a checkbox checked overriding defaultChecked with clean client render
1269 * renders a checkbox checked overriding defaultChecked with client render on top of good server markup
1270 * renders a checkbox checked overriding defaultChecked no matter the prop order with server string render
1271 +* renders a checkbox checked overriding defaultChecked no matter the prop order with server stream render
1272 * renders a checkbox checked overriding defaultChecked no matter the prop order with clean client render
1273 * renders a checkbox checked overriding defaultChecked no matter the prop order with client render on top of good server markup
1274 * renders a textarea with a value and an onChange with server string render
1275 +* renders a textarea with a value and an onChange with server stream render
1276 * renders a textarea with a value and an onChange with clean client render
1277 * renders a textarea with a value and an onChange with client render on top of good server markup
1278 * renders a textarea with a value and readOnly with server string render
1279 +* renders a textarea with a value and readOnly with server stream render
1280 * renders a textarea with a value and readOnly with clean client render
1281 * renders a textarea with a value and readOnly with client render on top of good server markup
1282 * renders a textarea with a value and no onChange/readOnly with server string render
1283 +* renders a textarea with a value and no onChange/readOnly with server stream render
1284 * renders a textarea with a value and no onChange/readOnly with clean client render
1285 * renders a textarea with a value and no onChange/readOnly with client render on top of good server markup
1286 * renders a textarea with a defaultValue with server string render
1287 +* renders a textarea with a defaultValue with server stream render
1288 * renders a textarea with a defaultValue with clean client render
1289 * renders a textarea with a defaultValue with client render on top of good server markup
1290 * renders a textarea value overriding defaultValue with server string render
1291 +* renders a textarea value overriding defaultValue with server stream render
1292 * renders a textarea value overriding defaultValue with clean client render
1293 * renders a textarea value overriding defaultValue with client render on top of good server markup
1294 * renders a textarea value overriding defaultValue no matter the prop order with server string render
1295 +* renders a textarea value overriding defaultValue no matter the prop order with server stream render
1296 * renders a textarea value overriding defaultValue no matter the prop order with clean client render
1297 * renders a textarea value overriding defaultValue no matter the prop order with client render on top of good server markup
1298 * renders a select with a value and an onChange with server string render
1299 +* renders a select with a value and an onChange with server stream render
1300 * renders a select with a value and an onChange with clean client render
1301 * renders a select with a value and an onChange with client render on top of good server markup
1302 * renders a select with a value and readOnly with server string render
1303 +* renders a select with a value and readOnly with server stream render
1304 * renders a select with a value and readOnly with clean client render
1305 * renders a select with a value and readOnly with client render on top of good server markup
1306 * renders a select with a multiple values and an onChange with server string render
1307 +* renders a select with a multiple values and an onChange with server stream render
1308 * renders a select with a multiple values and an onChange with clean client render
1309 * renders a select with a multiple values and an onChange with client render on top of good server markup
1310 * renders a select with a multiple values and readOnly with server string render
1311 +* renders a select with a multiple values and readOnly with server stream render
1312 * renders a select with a multiple values and readOnly with clean client render
1313 * renders a select with a multiple values and readOnly with client render on top of good server markup
1314 * renders a select with a value and no onChange/readOnly with server string render
1315 +* renders a select with a value and no onChange/readOnly with server stream render
1316 * renders a select with a value and no onChange/readOnly with clean client render
1317 * renders a select with a value and no onChange/readOnly with client render on top of good server markup
1318 * renders a select with a defaultValue with server string render
1319 +* renders a select with a defaultValue with server stream render
1320 * renders a select with a defaultValue with clean client render
1321 * renders a select with a defaultValue with client render on top of good server markup
1322 * renders a select value overriding defaultValue with server string render
1323 +* renders a select value overriding defaultValue with server stream render
1324 * renders a select value overriding defaultValue with clean client render
1325 * renders a select value overriding defaultValue with client render on top of good server markup
1326 * renders a select value overriding defaultValue no matter the prop order with server string render
1327 +* renders a select value overriding defaultValue no matter the prop order with server stream render
1328 * renders a select value overriding defaultValue no matter the prop order with clean client render
1329 * renders a select value overriding defaultValue no matter the prop order with client render on top of good server markup
1330 * renders a controlled text input with clean client render
@@ -1235,33 +1342,43 @@ src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
1342 * should not blow away user-selected value on successful reconnect to an uncontrolled select
1343 * should not blow away user-selected value on successful reconnect to an controlled select
1344 * renders class child with context with server string render
1345 +* renders class child with context with server stream render
1346 * renders class child with context with clean client render
1347 * renders class child with context with client render on top of good server markup
1348 * renders stateless child with context with server string render
1349 +* renders stateless child with context with server stream render
1350 * renders stateless child with context with clean client render
1351 * renders stateless child with context with client render on top of good server markup
1352 * renders class child without context with server string render
1353 +* renders class child without context with server stream render
1354 * renders class child without context with clean client render
1355 * renders class child without context with client render on top of good server markup
1356 * renders stateless child without context with server string render
1357 +* renders stateless child without context with server stream render
1358 * renders stateless child without context with clean client render
1359 * renders stateless child without context with client render on top of good server markup
1360 * renders class child with wrong context with server string render
1361 +* renders class child with wrong context with server stream render
1362 * renders class child with wrong context with clean client render
1363 * renders class child with wrong context with client render on top of good server markup
1364 * renders stateless child with wrong context with server string render
1365 +* renders stateless child with wrong context with server stream render
1366 * renders stateless child with wrong context with clean client render
1367 * renders stateless child with wrong context with client render on top of good server markup
1368 * renders with context passed through to a grandchild with server string render
1369 +* renders with context passed through to a grandchild with server stream render
1370 * renders with context passed through to a grandchild with clean client render
1371 * renders with context passed through to a grandchild with client render on top of good server markup
1372 * renders a child context overriding a parent context with server string render
1373 +* renders a child context overriding a parent context with server stream render
1374 * renders a child context overriding a parent context with clean client render
1375 * renders a child context overriding a parent context with client render on top of good server markup
1376 * renders a child context merged with a parent context with server string render
1377 +* renders a child context merged with a parent context with server stream render
1378 * renders a child context merged with a parent context with clean client render
1379 * renders a child context merged with a parent context with client render on top of good server markup
1380 * renders with a call to componentWillMount before getChildContext with server string render
1381 +* renders with a call to componentWillMount before getChildContext with server stream render
1382 * renders with a call to componentWillMount before getChildContext with clean client render
1383 * renders with a call to componentWillMount before getChildContext with client render on top of good server markup
1384 * throws when rendering if getChildContext exists without childContextTypes with server string render
scripts/rollup/bundles.js
+31 -4
@@ -138,12 +138,12 @@ const bundles = [
138 moduleName: 'ReactDOMServer',
139 sourceMap: false,
140 },
141 - entry: 'src/renderers/dom/ReactDOMServerStreamEntry',
141 + entry: 'src/renderers/dom/ReactDOMServerEntry',
142 externals: ['prop-types', 'prop-types/checkPropTypes'],
143 - fbEntry: 'src/renderers/dom/ReactDOMServerStreamEntry',
144 - hasteName: 'ReactDOMServerStream',
143 + fbEntry: 'src/renderers/dom/ReactDOMServerEntry',
144 + hasteName: 'ReactDOMServer',
145 isRenderer: true,
146 - label: 'dom-server-stream',
146 + label: 'dom-server-string',
147 manglePropertiesOnProd: false,
148 name: 'react-dom/server',
149 paths: [
@@ -154,6 +154,33 @@ const bundles = [
154 ],
155 },
156
157 + {
158 + babelOpts: babelOptsReact,
159 + bundleTypes: [NODE_DEV, NODE_PROD, FB_DEV, FB_PROD],
160 + config: {
161 + destDir: 'build/',
162 + globals: {
163 + react: 'React',
164 + },
165 + moduleName: 'ReactDOMNodeStream',
166 + sourceMap: false,
167 + },
168 + entry: 'src/renderers/dom/ReactDOMNodeStreamEntry',
169 + externals: ['prop-types', 'prop-types/checkPropTypes', 'stream'],
170 + fbEntry: 'src/renderers/dom/ReactDOMNodeStreamEntry',
171 + hasteName: 'ReactDOMNodeStream',
172 + isRenderer: true,
173 + label: 'dom-server-node-stream',
174 + manglePropertiesOnProd: false,
175 + name: 'react-dom/node-stream',
176 + paths: [
177 + 'src/renderers/dom/**/*.js',
178 + 'src/renderers/shared/**/*.js',
179 + 'src/ReactVersion.js',
180 + 'src/shared/**/*.js',
181 + ],
182 + },
183 +
184 /******* React ART *******/
185 {
186 babelOpts: babelOptsReactART,
scripts/rollup/results.json
+114 -58
@@ -17,44 +17,44 @@
17 "gzip": 2581
18 },
19 "React-dev.js (FB_DEV)": {
20 - "size": 61056,
21 - "gzip": 15809
20 + "size": 59124,
21 + "gzip": 15340
22 },
23 "React-prod.js (FB_PROD)": {
24 - "size": 29031,
25 - "gzip": 7690
24 + "size": 26781,
25 + "gzip": 7214
26 },
27 "react-dom.development.js (UMD_DEV)": {
28 - "size": 608162,
29 - "gzip": 139430
28 + "size": 613141,
29 + "gzip": 140395
30 },
31 "react-dom.production.min.js (UMD_PROD)": {
32 - "size": 125771,
33 - "gzip": 39564
32 + "size": 126584,
33 + "gzip": 39853
34 },
35 "react-dom.development.js (NODE_DEV)": {
36 - "size": 566845,
37 - "gzip": 129774
36 + "size": 570841,
37 + "gzip": 130520
38 },
39 "react-dom.production.min.js (NODE_PROD)": {
40 - "size": 122136,
41 - "gzip": 38292
40 + "size": 122880,
41 + "gzip": 38546
42 },
43 "ReactDOMFiber-dev.js (FB_DEV)": {
44 - "size": 566594,
45 - "gzip": 129950
44 + "size": 570125,
45 + "gzip": 130563
46 },
47 "ReactDOMFiber-prod.js (FB_PROD)": {
48 - "size": 426211,
49 - "gzip": 96543
48 + "size": 428502,
49 + "gzip": 96996
50 },
51 "react-dom-test-utils.development.js (NODE_DEV)": {
52 - "size": 52921,
53 - "gzip": 13634
52 + "size": 53025,
53 + "gzip": 13685
54 },
55 "ReactTestUtils-dev.js (FB_DEV)": {
56 - "size": 52865,
57 - "gzip": 13637
56 + "size": 52904,
57 + "gzip": 13646
58 },
59 "ReactDOMServerStack-dev.js (FB_DEV)": {
60 "size": 460810,
@@ -65,20 +65,20 @@
65 "gzip": 81957
66 },
67 "react-dom-server.development.js (UMD_DEV)": {
68 - "size": 306445,
69 - "gzip": 77153
68 + "size": 308329,
69 + "gzip": 77617
70 },
71 "react-dom-server.production.min.js (UMD_PROD)": {
72 - "size": 65952,
73 - "gzip": 22521
72 + "size": 66111,
73 + "gzip": 22613
74 },
75 "react-dom-server.development.js (NODE_DEV)": {
76 - "size": 265293,
77 - "gzip": 67673
76 + "size": 266194,
77 + "gzip": 67866
78 },
79 "react-dom-server.production.min.js (NODE_PROD)": {
80 - "size": 62302,
81 - "gzip": 21232
80 + "size": 62380,
81 + "gzip": 21260
82 },
83 "ReactDOMServerStream-dev.js (FB_DEV)": {
84 "size": 264750,
@@ -89,64 +89,120 @@
89 "gzip": 51047
90 },
91 "react-art.development.js (UMD_DEV)": {
92 - "size": 359725,
93 - "gzip": 79928
92 + "size": 362062,
93 + "gzip": 80236
94 },
95 "react-art.production.min.js (UMD_PROD)": {
96 - "size": 98725,
97 - "gzip": 29981
96 + "size": 99126,
97 + "gzip": 30132
98 },
99 "react-art.development.js (NODE_DEV)": {
100 - "size": 281066,
101 - "gzip": 59839
100 + "size": 283458,
101 + "gzip": 60201
102 },
103 "react-art.production.min.js (NODE_PROD)": {
104 - "size": 60110,
105 - "gzip": 18041
104 + "size": 60504,
105 + "gzip": 18189
106 },
107 "ReactARTFiber-dev.js (FB_DEV)": {
108 - "size": 280564,
109 - "gzip": 59807
108 + "size": 282891,
109 + "gzip": 60125
110 },
111 "ReactARTFiber-prod.js (FB_PROD)": {
112 - "size": 218560,
113 - "gzip": 45484
112 + "size": 220185,
113 + "gzip": 45704
114 },
115 "ReactNativeStack-dev.js (RN_DEV)": {
116 - "size": 185110,
117 - "gzip": 35690
116 + "size": 197039,
117 + "gzip": 36193
118 },
119 "ReactNativeStack-prod.js (RN_PROD)": {
120 - "size": 136665,
121 - "gzip": 26016
120 + "size": 136606,
121 + "gzip": 25990
122 },
123 "ReactNativeFiber-dev.js (RN_DEV)": {
124 - "size": 282752,
125 - "gzip": 50685
124 + "size": 301278,
125 + "gzip": 51431
126 },
127 "ReactNativeFiber-prod.js (RN_PROD)": {
128 - "size": 220854,
129 - "gzip": 37832
128 + "size": 221863,
129 + "gzip": 38015
130 },
131 "react-test-renderer.development.js (NODE_DEV)": {
132 - "size": 278560,
133 - "gzip": 58710
132 + "size": 280651,
133 + "gzip": 59110
134 },
135 "ReactTestRendererFiber-dev.js (FB_DEV)": {
136 - "size": 278049,
137 - "gzip": 58674
136 + "size": 280075,
137 + "gzip": 59030
138 },
139 "react-test-renderer-shallow.development.js (NODE_DEV)": {
140 - "size": 8108,
141 - "gzip": 2247
140 + "size": 8179,
141 + "gzip": 2288
142 },
143 "ReactShallowRenderer-dev.js (FB_DEV)": {
144 - "size": 8074,
145 - "gzip": 2234
144 + "size": 8080,
145 + "gzip": 2237
146 },
147 "react-noop-renderer.development.js (NODE_DEV)": {
148 - "size": 272256,
149 - "gzip": 56994
148 + "size": 274713,
149 + "gzip": 57491
150 + },
151 + "ReactHTMLString-dev.js (FB_DEV)": {
152 + "size": 265654,
153 + "gzip": 67793
154 + },
155 + "ReactHTMLString-prod.js (FB_PROD)": {
156 + "size": 197868,
157 + "gzip": 51197
158 + },
159 + "react-dom-stream.development.js (UMD_DEV)": {
160 + "size": 307410,
161 + "gzip": 77346
162 + },
163 + "react-dom-stream.production.min.js (UMD_PROD)": {
164 + "size": 66444,
165 + "gzip": 22648
166 + },
167 + "react-dom-stream.development.js (NODE_DEV)": {
168 + "size": 265257,
169 + "gzip": 67607
170 + },
171 + "react-dom-stream.production.min.js (NODE_PROD)": {
172 + "size": 62695,
173 + "gzip": 21279
174 + },
175 + "ReactHTMLStream-dev.js (FB_DEV)": {
176 + "size": 264745,
177 + "gzip": 67531
178 + },
179 + "ReactHTMLStream-prod.js (FB_PROD)": {
180 + "size": 197512,
181 + "gzip": 50920
182 + },
183 + "ReactDOMServer-dev.js (FB_DEV)": {
184 + "size": 265645,
185 + "gzip": 67788
186 + },
187 + "ReactDOMServer-prod.js (FB_PROD)": {
188 + "size": 197859,
189 + "gzip": 51191
190 + },
191 + "react-dom-node-stream.development.js (NODE_DEV)": {
192 + "size": 265427,
193 + "gzip": 67670
194 + },
195 + "react-dom-node-stream.production.min.js (NODE_PROD)": {
196 + "size": 62695,
197 + "gzip": 21279
198 + },
199 + "ReactDOMNodeStream-dev.js (FB_DEV)": {
200 + "size": 264918,
201 + "gzip": 67597
202 + },
203 + "ReactDOMNodeStream-prod.js (FB_PROD)": {
204 + "size": 197610,
205 + "gzip": 50956
206 }
207 }
208 }
\ No newline at end of file
src/node_modules/react-dom/node-stream.js new
+14
@@ -0,0 +1,14 @@
1 +/**
2 + * Copyright 2016-present Facebook. All Rights Reserved.
3 + *
4 + * @flow
5 + */
6 +
7 +'use strict';
8 +
9 +var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
10 +var useFiber = ReactDOMFeatureFlags.useFiber;
11 +
12 +module.exports = useFiber
13 + ? require('ReactDOMNodeStreamEntry')
14 + : null;
src/node_modules/react-dom/server.js
+1 -1
@@ -10,5 +10,5 @@ var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
10 var useFiber = ReactDOMFeatureFlags.useFiber;
11
12 module.exports = useFiber
13 - ? require('ReactDOMServerStreamEntry')
13 + ? require('ReactDOMServerEntry')
14 : require('ReactDOMServerStackEntry');
src/renderers/dom/ReactDOMNodeStreamEntry.js renamed
+5 -7
@@ -6,21 +6,19 @@
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 *
9 - * @providesModule ReactDOMServerStreamEntry
9 + * @providesModule ReactDOMNodeStreamEntry
10 */
11
12 'use strict';
13
14 var ReactDOMInjection = require('ReactDOMInjection');
15 -var ReactServerRenderer = require('ReactServerRenderer');
15 +var ReactDOMNodeStreamRenderer = require('ReactDOMNodeStreamRenderer');
16 var ReactVersion = require('ReactVersion');
17
18 ReactDOMInjection.inject();
19
20 -var ReactDOMServerStream = {
21 - renderToString: ReactServerRenderer.renderToString,
22 - renderToStaticMarkup: ReactServerRenderer.renderToStaticMarkup,
20 +module.exports = {
21 + renderToStream: ReactDOMNodeStreamRenderer.renderToStream,
22 + renderToStaticStream: ReactDOMNodeStreamRenderer.renderToStaticStream,
23 version: ReactVersion,
24 };
25 -
26 -module.exports = ReactDOMServerStream;
src/renderers/dom/ReactDOMNodeStreamRenderer.js new
+66
@@ -0,0 +1,66 @@
1 +/**
2 + * Copyright 2013-present, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule ReactDOMNodeStreamRenderer
10 + */
11 +
12 +'use strict';
13 +
14 +var invariant = require('fbjs/lib/invariant');
15 +var React = require('react');
16 +var ReactPartialRenderer = require('ReactPartialRenderer');
17 +
18 +var Readable = require('stream').Readable;
19 +
20 +// This is a Readable Node.js stream which wraps the ReactDOMPartialRenderer.
21 +class ReactMarkupReadableStream extends Readable {
22 + constructor(element, makeStaticMarkup) {
23 + // Calls the stream.Readable(options) constructor. Consider exposing built-in
24 + // features like highWaterMark in the future.
25 + super({});
26 + this.partialRenderer = new ReactPartialRenderer(element, makeStaticMarkup);
27 + }
28 +
29 + _read(size) {
30 + try {
31 + this.push(this.partialRenderer.read(size));
32 + } catch (err) {
33 + this.emit('error', err);
34 + }
35 + }
36 +}
37 +/**
38 + * Render a ReactElement to its initial HTML. This should only be used on the
39 + * server.
40 + * See https://facebook.github.io/react/docs/react-dom-stream.html#rendertostream
41 + */
42 +function renderToStream(element) {
43 + invariant(
44 + React.isValidElement(element),
45 + 'renderToStream(): You must pass a valid ReactElement.',
46 + );
47 + return new ReactMarkupReadableStream(element, false);
48 +}
49 +
50 +/**
51 + * Similar to renderToStream, except this doesn't create extra DOM attributes
52 + * such as data-react-id that React uses internally.
53 + * See https://facebook.github.io/react/docs/react-dom-stream.html#rendertostaticstream
54 + */
55 +function renderToStaticStream(element) {
56 + invariant(
57 + React.isValidElement(element),
58 + 'renderToStaticStream(): You must pass a valid ReactElement.',
59 + );
60 + return new ReactMarkupReadableStream(element, true);
61 +}
62 +
63 +module.exports = {
64 + renderToStream: renderToStream,
65 + renderToStaticStream: renderToStaticStream,
66 +};
src/renderers/dom/ReactDOMServerEntry.js new
+24
@@ -0,0 +1,24 @@
1 +/**
2 + * Copyright 2013-present, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule ReactDOMServerEntry
10 + */
11 +
12 +'use strict';
13 +
14 +var ReactDOMInjection = require('ReactDOMInjection');
15 +var ReactDOMStringRenderer = require('ReactDOMStringRenderer');
16 +var ReactVersion = require('ReactVersion');
17 +
18 +ReactDOMInjection.inject();
19 +
20 +module.exports = {
21 + renderToString: ReactDOMStringRenderer.renderToString,
22 + renderToStaticMarkup: ReactDOMStringRenderer.renderToStaticMarkup,
23 + version: ReactVersion,
24 +};
src/renderers/dom/ReactDOMStringRenderer.js new
+53
@@ -0,0 +1,53 @@
1 +/**
2 + * Copyright 2013-present, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule ReactDOMStringRenderer
10 + */
11 +
12 +'use strict';
13 +
14 +var invariant = require('fbjs/lib/invariant');
15 +var React = require('react');
16 +var ReactMarkupChecksum = require('ReactMarkupChecksum');
17 +var ReactPartialRenderer = require('ReactPartialRenderer');
18 +
19 +/**
20 + * Render a ReactElement to its initial HTML. This should only be used on the
21 + * server.
22 + * See https://facebook.github.io/react/docs/react-dom-server.html#rendertostring
23 + */
24 +function renderToString(element) {
25 + invariant(
26 + React.isValidElement(element),
27 + 'renderToString(): You must pass a valid ReactElement.',
28 + );
29 + var renderer = new ReactPartialRenderer(element, false);
30 + var markup = renderer.read(Infinity);
31 + markup = ReactMarkupChecksum.addChecksumToMarkup(markup);
32 + return markup;
33 +}
34 +
35 +/**
36 + * Similar to renderToString, except this doesn't create extra DOM attributes
37 + * such as data-react-id that React uses internally.
38 + * See https://facebook.github.io/react/docs/react-dom-server.html#rendertostaticmarkup
39 + */
40 +function renderToStaticMarkup(element) {
41 + invariant(
42 + React.isValidElement(element),
43 + 'renderToStaticMarkup(): You must pass a valid ReactElement.',
44 + );
45 + var renderer = new ReactPartialRenderer(element, true);
46 + var markup = renderer.read(Infinity);
47 + return markup;
48 +}
49 +
50 +module.exports = {
51 + renderToString: renderToString,
52 + renderToStaticMarkup: renderToStaticMarkup,
53 +};
src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
+66 -16
@@ -11,14 +11,18 @@
11
12 'use strict';
13
14 +let ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
15 +
16 let ExecutionEnvironment;
17 let PropTypes;
18 let React;
19 let ReactDOM;
20 let ReactDOMServer;
19 -let ReactDOMFeatureFlags;
21 +let ReactDOMNodeStream;
22 let ReactTestUtils;
23
24 +const stream = require('stream');
25 +
26 // Helper functions for rendering tests
27 // ====================================
28
@@ -87,6 +91,42 @@ async function serverRender(reactElement, errorCount = 0) {
91 return domElement.firstChild;
92 }
93
94 +// this just drains a readable piped into it to a string, which can be accessed
95 +// via .buffer.
96 +class DrainWritable extends stream.Writable {
97 + constructor(options) {
98 + super(options);
99 + this.buffer = '';
100 + }
101 +
102 + _write(chunk, encoding, cb) {
103 + this.buffer += chunk;
104 + cb();
105 + }
106 +}
107 +
108 +async function renderIntoStream(reactElement, errorCount = 0) {
109 + return await expectErrors(
110 + () =>
111 + new Promise(resolve => {
112 + let writable = new DrainWritable();
113 + ReactDOMNodeStream.renderToStream(reactElement).pipe(writable);
114 + writable.on('finish', () => resolve(writable.buffer));
115 + }),
116 + errorCount,
117 + );
118 +}
119 +
120 +// Renders text using node stream SSR and then stuffs it into a DOM node;
121 +// returns the DOM element that corresponds with the reactElement.
122 +// Does not render on client or perform client-side revival.
123 +async function streamRender(reactElement, errorCount = 0) {
124 + const markup = await renderIntoStream(reactElement, errorCount);
125 + var domElement = document.createElement('div');
126 + domElement.innerHTML = markup;
127 + return domElement.firstChild;
128 +}
129 +
130 const clientCleanRender = (element, errorCount = 0) => {
131 const div = document.createElement('div');
132 return renderIntoDom(element, div, errorCount);
@@ -149,6 +189,9 @@ const clientRenderOnBadMarkup = async (element, errorCount = 0) => {
189 // as that will not work in the server string scenario.
190 function itRenders(desc, testFn) {
191 it(`renders ${desc} with server string render`, () => testFn(serverRender));
192 + if (ReactDOMFeatureFlags.useFiber) {
193 + it(`renders ${desc} with server stream render`, () => testFn(streamRender));
194 + }
195 itClientRenders(desc, testFn);
196 }
197
@@ -246,6 +289,7 @@ function resetModules() {
289 ReactDOM = require('react-dom');
290 ReactDOMServer = require('react-dom/server');
291 ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
292 + ReactDOMNodeStream = require('react-dom/node-stream');
293 ReactTestUtils = require('react-dom/test-utils');
294 // TODO: can we express this test with only public API?
295 ExecutionEnvironment = require('ExecutionEnvironment');
@@ -558,7 +602,7 @@ describe('ReactDOMServerIntegration', () => {
602 if (ReactDOMFeatureFlags.useFiber) {
603 // with Fiber, there are just three separate text node children,
604 // each of which is blank.
561 - if (render === serverRender) {
605 + if (render === serverRender || render === streamRender) {
606 // For plain server markup result we expect six comment nodes.
607 expect(e.childNodes.length).toBe(6);
608 expect(e.textContent).toBe('');
@@ -581,7 +625,7 @@ describe('ReactDOMServerIntegration', () => {
625 const e = await render(<div>{' '}{' '}{' '}</div>);
626 if (ReactDOMFeatureFlags.useFiber) {
627 // with Fiber, there are just three text nodes.
584 - if (render === serverRender) {
628 + if (render === serverRender || render === streamRender) {
629 expect(e.childNodes.length).toBe(9);
630 expectTextNode(e.childNodes[1], ' ');
631 expectTextNode(e.childNodes[4], ' ');
@@ -605,7 +649,10 @@ describe('ReactDOMServerIntegration', () => {
649 itRenders('a div with text sibling to a node', async render => {
650 const e = await render(<div>Text<span>More Text</span></div>);
651 let spanNode;
608 - if (ReactDOMFeatureFlags.useFiber && render !== serverRender) {
652 + if (
653 + ReactDOMFeatureFlags.useFiber &&
654 + (render !== serverRender && render !== streamRender)
655 + ) {
656 // with Fiber, there are only two children, the "Text" text node and
657 // the span element.
658 expect(e.childNodes.length).toBe(2);
@@ -616,7 +663,10 @@ describe('ReactDOMServerIntegration', () => {
663 expect(e.childNodes.length).toBe(4);
664 spanNode = e.childNodes[3];
665 }
619 - if (ReactDOMFeatureFlags.useFiber && render === serverRender) {
666 + if (
667 + ReactDOMFeatureFlags.useFiber &&
668 + (render === serverRender || render === streamRender)
669 + ) {
670 expectTextNode(e.childNodes[1], 'Text');
671 } else {
672 expectTextNode(e.childNodes[0], 'Text');
@@ -644,7 +694,7 @@ describe('ReactDOMServerIntegration', () => {
694 const e = await render(<div>{''}foo</div>);
695 if (ReactDOMFeatureFlags.useFiber) {
696 // with Fiber, there are just two text nodes.
647 - if (render === serverRender) {
697 + if (render === serverRender || render === streamRender) {
698 expect(e.childNodes.length).toBe(5);
699 expectTextNode(e.childNodes[3], 'foo');
700 } else {
@@ -666,7 +716,7 @@ describe('ReactDOMServerIntegration', () => {
716 const e = await render(<div>foo{''}</div>);
717 if (ReactDOMFeatureFlags.useFiber) {
718 // with Fiber, there are just two text nodes.
669 - if (render === serverRender) {
719 + if (render === serverRender || render === streamRender) {
720 expect(e.childNodes.length).toBe(5);
721 expectTextNode(e.childNodes[1], 'foo');
722 } else {
@@ -688,7 +738,7 @@ describe('ReactDOMServerIntegration', () => {
738 const e = await render(<div>{'foo'}{'bar'}</div>);
739 if (ReactDOMFeatureFlags.useFiber) {
740 // with Fiber, there are just two text nodes.
691 - if (render === serverRender) {
741 + if (render === serverRender || render === streamRender) {
742 expect(e.childNodes.length).toBe(6);
743 expectTextNode(e.childNodes[1], 'foo');
744 expectTextNode(e.childNodes[4], 'bar');
@@ -723,7 +773,7 @@ describe('ReactDOMServerIntegration', () => {
773 const e = await render(<div>{'foo'}{40}</div>);
774 if (ReactDOMFeatureFlags.useFiber) {
775 // with Fiber, there are just two text nodes.
726 - if (render === serverRender) {
776 + if (render === serverRender || render === streamRender) {
777 expect(e.childNodes.length).toBe(6);
778 expectTextNode(e.childNodes[1], 'foo');
779 expectTextNode(e.childNodes[4], '40');
@@ -763,7 +813,7 @@ describe('ReactDOMServerIntegration', () => {
813 const e = await render(<div><NullComponent /></div>);
814 if (ReactDOMFeatureFlags.useFiber) {
815 // with Fiber, an empty component results in no markup.
766 - if (render === serverRender) {
816 + if (render === serverRender || render === streamRender) {
817 expect(e.childNodes.length).toBe(1);
818 expectEmptyNode(e.firstChild);
819 } else {
@@ -781,7 +831,7 @@ describe('ReactDOMServerIntegration', () => {
831 const e = await render(<div>{null}foo</div>);
832 if (ReactDOMFeatureFlags.useFiber) {
833 // with Fiber, there is just one text node.
784 - if (render === serverRender) {
834 + if (render === serverRender || render === streamRender) {
835 expect(e.childNodes.length).toBe(3);
836 expectTextNode(e.childNodes[1], 'foo');
837 } else {
@@ -799,7 +849,7 @@ describe('ReactDOMServerIntegration', () => {
849 const e = await render(<div>{false}foo</div>);
850 if (ReactDOMFeatureFlags.useFiber) {
851 // with Fiber, there is just one text node.
802 - if (render === serverRender) {
852 + if (render === serverRender || render === streamRender) {
853 expect(e.childNodes.length).toBe(3);
854 expectTextNode(e.childNodes[1], 'foo');
855 } else {
@@ -817,7 +867,7 @@ describe('ReactDOMServerIntegration', () => {
867 const e = await render(<div>{false}{null}foo{null}{false}</div>);
868 if (ReactDOMFeatureFlags.useFiber) {
869 // with Fiber, there is just one text node.
820 - if (render === serverRender) {
870 + if (render === serverRender || render === streamRender) {
871 expect(e.childNodes.length).toBe(3);
872 expectTextNode(e.childNodes[1], 'foo');
873 } else {
@@ -1022,7 +1072,7 @@ describe('ReactDOMServerIntegration', () => {
1072 if (ReactDOMFeatureFlags.useFiber) {
1073 // with Fiber, there are three children: the child1 element, a
1074 // single space text node, and the child2 element.
1025 - if (render === serverRender) {
1075 + if (render === serverRender || render === streamRender) {
1076 expect(e.childNodes.length).toBe(5);
1077 child1 = e.childNodes[0];
1078 textNode = e.childNodes[2];
@@ -1058,7 +1108,7 @@ describe('ReactDOMServerIntegration', () => {
1108 if (ReactDOMFeatureFlags.useFiber) {
1109 // with Fiber, there are three children: a one-space text node, the
1110 // child element, and a two-space text node.
1061 - if (render === serverRender) {
1111 + if (render === serverRender || render === streamRender) {
1112 expect(e.childNodes.length).toBe(7);
1113 textNode1 = e.childNodes[1];
1114 child = e.childNodes[3];
@@ -1100,7 +1150,7 @@ describe('ReactDOMServerIntegration', () => {
1150 );
1151 if (ReactDOMFeatureFlags.useFiber) {
1152 // with Fiber, there are just two text nodes.
1103 - if (render === serverRender) {
1153 + if (render === serverRender || render === streamRender) {
1154 expect(e.childNodes.length).toBe(6);
1155 expectTextNode(e.childNodes[1], '<span>Text1&quot;</span>');
1156 expectTextNode(e.childNodes[4], '<span>Text2&quot;</span>');
src/renderers/shared/server/ReactPartialRenderer.js renamed
+6 -39
@@ -6,7 +6,7 @@
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 *
9 - * @providesModule ReactServerRenderer
9 + * @providesModule ReactPartialRenderer
10 */
11
12 'use strict';
@@ -16,7 +16,6 @@ var DOMPropertyOperations = require('DOMPropertyOperations');
16 var {registrationNameModules} = require('EventPluginRegistry');
17 var React = require('react');
18 var ReactControlledValuePropTypes = require('ReactControlledValuePropTypes');
19 -var ReactMarkupChecksum = require('ReactMarkupChecksum');
19
20 var assertValidProps = require('assertValidProps');
21 var checkPropTypes = require('prop-types/checkPropTypes');
@@ -354,6 +353,10 @@ class ReactDOMServerRenderer {
353 }
354
355 read(bytes) {
356 + if (this.exhausted) {
357 + return null;
358 + }
359 +
360 var out = '';
361 while (out.length < bytes) {
362 if (this.stack.length === 0) {
@@ -687,40 +690,4 @@ class ReactDOMServerRenderer {
690 }
691 }
692
690 -/**
691 - * Render a ReactElement to its initial HTML. This should only be used on the
692 - * server.
693 - * See https://facebook.github.io/react/docs/react-dom-server.html#rendertostring
694 - */
695 -function renderToString(element) {
696 - invariant(
697 - React.isValidElement(element),
698 - 'renderToString(): You must pass a valid ReactElement.',
699 - );
700 - var renderer = new ReactDOMServerRenderer(element, false);
701 - var markup = renderer.read(Infinity);
702 - markup = ReactMarkupChecksum.addChecksumToMarkup(markup);
703 - return markup;
704 -}
705 -
706 -/**
707 - * Similar to renderToString, except this doesn't create extra DOM attributes
708 - * such as data-react-id that React uses internally.
709 - * See https://facebook.github.io/react/docs/react-dom-server.html#rendertostaticmarkup
710 - */
711 -function renderToStaticMarkup(element) {
712 - invariant(
713 - React.isValidElement(element),
714 - 'renderToStaticMarkup(): You must pass a valid ReactElement.',
715 - );
716 - var renderer = new ReactDOMServerRenderer(element, true);
717 - var markup = renderer.read(Infinity);
718 - return markup;
719 -}
720 -
721 -var ReactServerRenderer = {
722 - renderToString: renderToString,
723 - renderToStaticMarkup: renderToStaticMarkup,
724 -};
725 -
726 -module.exports = ReactServerRenderer;
693 +module.exports = ReactDOMServerRenderer;