Use single entry point for SSR via browser field (#10362)
* Use single entry point for SSR via browser field * Add server.browser entry point and smoke tests * Tweak bundle naming * Fix import * Re-record * Fix the robot nits * Add resetModules for some extra isolation
Dan Abramov committed
Aug 3, 2017 at 00:41 UTC
fc86ef0f3d5c3b93121d245512eb686617e47527
12 files changed
+204
-178
packages/react-dom/node-stream.js
deleted
-7
@@ -1,7 +0,0 @@
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
-}
packages/react-dom/package.json
+4
-1
@@ -27,12 +27,15 @@
27
"README.md",
28
"index.js",
29
"server.js",
30
- "node-stream.js",
30
+ "server.browser.js",
31
"test-utils.js",
32
"unstable-native-dependencies.js",
33
"cjs/",
34
"umd/"
35
],
36
+ "browser": {
37
+ "./server.js": "./server.browser.js"
38
+ },
39
"browserify": {
40
"transform": [
41
"loose-envify"
packages/react-dom/server.browser.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-server.browser.production.min.js');
5
+} else {
6
+ module.exports = require('./cjs/react-dom-server.browser.development.js');
7
+}
packages/react-dom/server.js
+2
-2
@@ -1,7 +1,7 @@
1
'use strict';
2
3
if (process.env.NODE_ENV === 'production') {
4
- module.exports = require('./cjs/react-dom-server.production.min.js');
4
+ module.exports = require('./cjs/react-dom-server.node.production.min.js');
5
} else {
6
- module.exports = require('./cjs/react-dom-server.development.js');
6
+ module.exports = require('./cjs/react-dom-server.node.development.js');
7
}
scripts/rollup/bundles.js
+7
-7
@@ -172,14 +172,14 @@ const bundles = [
172
moduleName: 'ReactDOMServer',
173
sourceMap: false,
174
},
175
- entry: 'src/renderers/dom/ReactDOMServerEntry',
175
+ entry: 'src/renderers/dom/ReactDOMServerBrowserEntry',
176
externals: ['prop-types', 'prop-types/checkPropTypes'],
177
- fbEntry: 'src/renderers/dom/ReactDOMServerEntry',
177
+ fbEntry: 'src/renderers/dom/ReactDOMServerBrowserEntry',
178
hasteName: 'ReactDOMServer',
179
isRenderer: true,
180
- label: 'dom-server-string',
180
+ label: 'dom-server-browser',
181
manglePropertiesOnProd: false,
182
- name: 'react-dom/server',
182
+ name: 'react-dom/server.browser',
183
paths: [
184
'src/renderers/dom/**/*.js',
185
'src/renderers/shared/**/*.js',
@@ -199,12 +199,12 @@ const bundles = [
199
moduleName: 'ReactDOMNodeStream',
200
sourceMap: false,
201
},
202
- entry: 'src/renderers/dom/ReactDOMNodeStreamEntry',
202
+ entry: 'src/renderers/dom/ReactDOMServerNodeEntry',
203
externals: ['prop-types', 'prop-types/checkPropTypes', 'stream'],
204
isRenderer: true,
205
- label: 'dom-server-node-stream',
205
+ label: 'dom-server-server-node',
206
manglePropertiesOnProd: false,
207
- name: 'react-dom/node-stream',
207
+ name: 'react-dom/server.node',
208
paths: [
209
'src/renderers/dom/**/*.js',
210
'src/renderers/shared/**/*.js',
scripts/rollup/results.json
+90
-146
@@ -25,92 +25,116 @@
25
"gzip": 6703
26
},
27
"react-dom.development.js (UMD_DEV)": {
28
- "size": 639824,
29
- "gzip": 145999
28
+ "size": 640604,
29
+ "gzip": 146616
30
},
31
"react-dom.production.min.js (UMD_PROD)": {
32
- "size": 121920,
33
- "gzip": 38871
32
+ "size": 121735,
33
+ "gzip": 38859
34
},
35
"react-dom.development.js (NODE_DEV)": {
36
- "size": 599220,
37
- "gzip": 136402
36
+ "size": 599999,
37
+ "gzip": 136960
38
},
39
"react-dom.production.min.js (NODE_PROD)": {
40
- "size": 118838,
41
- "gzip": 37788
40
+ "size": 118657,
41
+ "gzip": 37769
42
},
43
"ReactDOMFiber-dev.js (FB_DEV)": {
44
- "size": 595749,
45
- "gzip": 135868
44
+ "size": 596499,
45
+ "gzip": 136409
46
},
47
"ReactDOMFiber-prod.js (FB_PROD)": {
48
- "size": 431003,
49
- "gzip": 96867
48
+ "size": 430689,
49
+ "gzip": 96928
50
},
51
"react-dom-test-utils.development.js (NODE_DEV)": {
52
- "size": 56074,
53
- "gzip": 14162
52
+ "size": 55917,
53
+ "gzip": 14141
54
},
55
"ReactTestUtils-dev.js (FB_DEV)": {
56
- "size": 55864,
57
- "gzip": 14128
56
+ "size": 55707,
57
+ "gzip": 14105
58
},
59
- "ReactDOMServerStack-dev.js (FB_DEV)": {
60
- "size": 460810,
61
- "gzip": 111966
59
+ "react-dom-unstable-native-dependencies.development.js (UMD_DEV)": {
60
+ "size": 89486,
61
+ "gzip": 22619
62
},
63
- "ReactDOMServerStack-prod.js (FB_PROD)": {
64
- "size": 338222,
65
- "gzip": 81957
63
+ "react-dom-unstable-native-dependencies.production.min.js (UMD_PROD)": {
64
+ "size": 18338,
65
+ "gzip": 5956
66
},
67
- "react-dom-server.development.js (UMD_DEV)": {
68
- "size": 122993,
69
- "gzip": 31032
67
+ "react-dom-unstable-native-dependencies.development.js (NODE_DEV)": {
68
+ "size": 82914,
69
+ "gzip": 20689
70
},
71
- "react-dom-server.production.min.js (UMD_PROD)": {
72
- "size": 22819,
73
- "gzip": 8627
71
+ "react-dom-unstable-native-dependencies.production.min.js (NODE_PROD)": {
72
+ "size": 16978,
73
+ "gzip": 5429
74
},
75
- "react-dom-server.development.js (NODE_DEV)": {
76
- "size": 92141,
77
- "gzip": 23593
75
+ "ReactDOMUnstableNativeDependencies-dev.js (FB_DEV)": {
76
+ "size": 82613,
77
+ "gzip": 20656
78
},
79
- "react-dom-server.production.min.js (NODE_PROD)": {
80
- "size": 21214,
81
- "gzip": 8026
79
+ "ReactDOMUnstableNativeDependencies-prod.js (FB_PROD)": {
80
+ "size": 67256,
81
+ "gzip": 16011
82
+ },
83
+ "react-dom-server.browser.development.js (UMD_DEV)": {
84
+ "size": 123259,
85
+ "gzip": 31130
86
+ },
87
+ "react-dom-server.browser.production.min.js (UMD_PROD)": {
88
+ "size": 22069,
89
+ "gzip": 8359
90
+ },
91
+ "react-dom-server.browser.development.js (NODE_DEV)": {
92
+ "size": 92395,
93
+ "gzip": 23727
94
+ },
95
+ "react-dom-server.browser.production.min.js (NODE_PROD)": {
96
+ "size": 20470,
97
+ "gzip": 7751
98
+ },
99
+ "ReactDOMServer-dev.js (FB_DEV)": {
100
+ "size": 91478,
101
+ "gzip": 23641
102
+ },
103
+ "ReactDOMServer-prod.js (FB_PROD)": {
104
+ "size": 49904,
105
+ "gzip": 13944
106
},
83
- "ReactDOMServerStream-dev.js (FB_DEV)": {
84
- "size": 264750,
85
- "gzip": 67600
107
+ "react-dom-server.node.development.js (NODE_DEV)": {
108
+ "size": 95082,
109
+ "gzip": 24294
110
},
87
- "ReactDOMServerStream-prod.js (FB_PROD)": {
88
- "size": 198041,
89
- "gzip": 51047
111
+ "react-dom-server.node.production.min.js (NODE_PROD)": {
112
+ "size": 21375,
113
+ "gzip": 8033
114
},
115
"react-art.development.js (UMD_DEV)": {
92
- "size": 373050,
93
- "gzip": 82463
116
+ "size": 373020,
117
+ "gzip": 82667
118
},
119
"react-art.production.min.js (UMD_PROD)": {
96
- "size": 94183,
97
- "gzip": 29145
120
+ "size": 94024,
121
+ "gzip": 29099
122
},
123
"react-art.development.js (NODE_DEV)": {
100
- "size": 294419,
101
- "gzip": 62436
124
+ "size": 294390,
125
+ "gzip": 62633
126
},
127
"react-art.production.min.js (NODE_PROD)": {
104
- "size": 55748,
105
- "gzip": 17250
128
+ "size": 55594,
129
+ "gzip": 17147
130
},
131
"ReactARTFiber-dev.js (FB_DEV)": {
108
- "size": 293279,
109
- "gzip": 62507
132
+ "size": 293221,
133
+ "gzip": 62686
134
},
135
"ReactARTFiber-prod.js (FB_PROD)": {
112
- "size": 220571,
113
- "gzip": 45660
136
+ "size": 220287,
137
+ "gzip": 45716
138
},
139
"ReactNativeStack-dev.js (RN_DEV)": {
140
"size": 188445,
@@ -121,112 +145,32 @@
145
"gzip": 26398
146
},
147
"ReactNativeFiber-dev.js (RN_DEV)": {
124
- "size": 290148,
125
- "gzip": 52574
148
+ "size": 290448,
149
+ "gzip": 52727
150
},
151
"ReactNativeFiber-prod.js (RN_PROD)": {
128
- "size": 224144,
129
- "gzip": 38909
152
+ "size": 224421,
153
+ "gzip": 39029
154
},
155
"react-test-renderer.development.js (NODE_DEV)": {
132
- "size": 291782,
133
- "gzip": 61299
156
+ "size": 292225,
157
+ "gzip": 61530
158
},
159
"ReactTestRendererFiber-dev.js (FB_DEV)": {
136
- "size": 290600,
137
- "gzip": 61383
160
+ "size": 291017,
161
+ "gzip": 61598
162
},
163
"react-test-renderer-shallow.development.js (NODE_DEV)": {
140
- "size": 10302,
141
- "gzip": 2587
164
+ "size": 10145,
165
+ "gzip": 2581
166
},
167
"ReactShallowRenderer-dev.js (FB_DEV)": {
144
- "size": 10208,
145
- "gzip": 2541
168
+ "size": 10051,
169
+ "gzip": 2533
170
},
171
"react-noop-renderer.development.js (NODE_DEV)": {
148
- "size": 285709,
149
- "gzip": 59710
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": 91224,
185
- "gzip": 23517
186
- },
187
- "ReactDOMServer-prod.js (FB_PROD)": {
188
- "size": 55353,
189
- "gzip": 15240
190
- },
191
- "react-dom-node-stream.development.js (NODE_DEV)": {
192
- "size": 93872,
193
- "gzip": 24085
194
- },
195
- "react-dom-node-stream.production.min.js (NODE_PROD)": {
196
- "size": 22057,
197
- "gzip": 8338
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
- "react-dom-unstable-native-dependencies.development.js (UMD_DEV)": {
208
- "size": 89486,
209
- "gzip": 22619
210
- },
211
- "react-dom-unstable-native-dependencies.production.min.js (UMD_PROD)": {
212
- "size": 18338,
213
- "gzip": 5956
214
- },
215
- "react-dom-unstable-native-dependencies.development.js (NODE_DEV)": {
216
- "size": 82914,
217
- "gzip": 20689
218
- },
219
- "react-dom-unstable-native-dependencies.production.min.js (NODE_PROD)": {
220
- "size": 16978,
221
- "gzip": 5429
222
- },
223
- "ReactDOMUnstableNativeDependencies-dev.js (FB_DEV)": {
224
- "size": 82613,
225
- "gzip": 20656
226
- },
227
- "ReactDOMUnstableNativeDependencies-prod.js (FB_PROD)": {
228
- "size": 67256,
229
- "gzip": 16011
172
+ "size": 286152,
173
+ "gzip": 59943
174
}
175
}
176
}
\ No newline at end of file
src/node_modules/react-dom/server.browser.js
renamed
+2
-2
@@ -10,5 +10,5 @@ var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
10
var useFiber = ReactDOMFeatureFlags.useFiber;
11
12
module.exports = useFiber
13
- ? require('ReactDOMNodeStreamEntry')
14
- : null;
13
+ ? require('ReactDOMServerBrowserEntry')
14
+ : require('ReactDOMServerStackEntry');
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('ReactDOMServerEntry')
13
+ ? require('ReactDOMServerNodeEntry')
14
: require('ReactDOMServerStackEntry');
src/renderers/dom/ReactDOMServerBrowserEntry.js
renamed
+16
-1
@@ -6,18 +6,33 @@
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
9
+ * @providesModule ReactDOMServerBrowserEntry
10
*/
11
12
'use strict';
13
14
var ReactDOMStringRenderer = require('ReactDOMStringRenderer');
15
var ReactVersion = require('ReactVersion');
16
+var invariant = require('fbjs/lib/invariant');
17
18
require('ReactDOMInjection');
19
20
module.exports = {
21
renderToString: ReactDOMStringRenderer.renderToString,
22
renderToStaticMarkup: ReactDOMStringRenderer.renderToStaticMarkup,
23
+ renderToStream() {
24
+ invariant(
25
+ false,
26
+ 'ReactDOMServer.renderToStream(): The streaming API is not available ' +
27
+ 'in the browser. Use ReactDOMServer.renderToString() instead.',
28
+ );
29
+ },
30
+ renderToStaticStream() {
31
+ invariant(
32
+ false,
33
+ 'ReactDOMServer.renderToStaticStream(): The streaming API is not available ' +
34
+ 'in the browser. Use ReactDOMServer.renderToStaticMarkup() instead.',
35
+ );
36
+ },
37
version: ReactVersion,
38
};
src/renderers/dom/ReactDOMServerNodeEntry.js
renamed
+4
-1
@@ -6,17 +6,20 @@
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 ReactDOMNodeStreamEntry
9
+ * @providesModule ReactDOMServerNodeEntry
10
*/
11
12
'use strict';
13
14
+var ReactDOMStringRenderer = require('ReactDOMStringRenderer');
15
var ReactDOMNodeStreamRenderer = require('ReactDOMNodeStreamRenderer');
16
var ReactVersion = require('ReactVersion');
17
18
require('ReactDOMInjection');
19
20
module.exports = {
21
+ renderToString: ReactDOMStringRenderer.renderToString,
22
+ renderToStaticMarkup: ReactDOMStringRenderer.renderToStaticMarkup,
23
renderToStream: ReactDOMNodeStreamRenderer.renderToStream,
24
renderToStaticStream: ReactDOMNodeStreamRenderer.renderToStaticStream,
25
version: ReactVersion,
src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
+1
-10
@@ -18,7 +18,6 @@ let PropTypes;
18
let React;
19
let ReactDOM;
20
let ReactDOMServer;
21
-let ReactDOMNodeStream;
21
let ReactTestUtils;
22
23
const stream = require('stream');
@@ -120,7 +119,7 @@ async function renderIntoStream(reactElement, errorCount = 0) {
119
() =>
120
new Promise(resolve => {
121
let writable = new DrainWritable();
123
- ReactDOMNodeStream.renderToStream(reactElement).pipe(writable);
122
+ ReactDOMServer.renderToStream(reactElement).pipe(writable);
123
writable.on('finish', () => resolve(writable.buffer));
124
}),
125
errorCount,
@@ -347,14 +346,6 @@ function resetModules() {
346
}
347
require('ReactFeatureFlags').disableNewFiberFeatures = false;
348
ReactDOMServer = require('react-dom/server');
350
-
351
- // Finally, reset modules one more time before importing the stream renderer.
352
- jest.resetModuleRegistry();
353
- if (typeof onAfterResetModules === 'function') {
354
- onAfterResetModules();
355
- }
356
- require('ReactFeatureFlags').disableNewFiberFeatures = false;
357
- ReactDOMNodeStream = require('react-dom/node-stream');
349
}
350
351
describe('ReactDOMServerIntegration', () => {
src/renderers/dom/shared/__tests__/ReactServerRenderingBrowser-test.js
new
+70
@@ -0,0 +1,70 @@
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
+ * @emails react-core
10
+ */
11
+
12
+'use strict';
13
+
14
+var React;
15
+var ReactDOMServer;
16
+var ReactDOMServerBrowser;
17
+
18
+var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
19
+
20
+describe('ReactServerRenderingBrowser', () => {
21
+ beforeEach(() => {
22
+ jest.resetModules();
23
+ React = require('react');
24
+ ReactDOMServer = require('react-dom/server');
25
+ // For extra isolation between what would be two bundles on npm
26
+ jest.resetModuleRegistry();
27
+ ReactDOMServerBrowser = require('react-dom/server.browser');
28
+ });
29
+
30
+ it('provides the same top-level API as react-dom/server', () => {
31
+ expect(Object.keys(ReactDOMServerBrowser)).toEqual(
32
+ Object.keys(ReactDOMServer),
33
+ );
34
+ });
35
+
36
+ it('returns the same results as react-dom/server', () => {
37
+ class Nice extends React.Component {
38
+ render() {
39
+ return <h2>I am feeling very good today, thanks, how are you?</h2>;
40
+ }
41
+ }
42
+ function Greeting() {
43
+ return (
44
+ <div>
45
+ <h1>How are you?</h1>
46
+ <Nice />
47
+ </div>
48
+ );
49
+ }
50
+ expect(ReactDOMServerBrowser.renderToString(<Greeting />)).toEqual(
51
+ ReactDOMServer.renderToString(<Greeting />),
52
+ );
53
+ expect(ReactDOMServerBrowser.renderToStaticMarkup(<Greeting />)).toEqual(
54
+ ReactDOMServer.renderToStaticMarkup(<Greeting />),
55
+ );
56
+ });
57
+
58
+ if (ReactDOMFeatureFlags.useFiber) {
59
+ it('throws meaningfully for server-only APIs', () => {
60
+ expect(() => ReactDOMServerBrowser.renderToStream(<div />)).toThrow(
61
+ 'ReactDOMServer.renderToStream(): The streaming API is not available ' +
62
+ 'in the browser. Use ReactDOMServer.renderToString() instead.',
63
+ );
64
+ expect(() => ReactDOMServerBrowser.renderToStaticStream(<div />)).toThrow(
65
+ 'ReactDOMServer.renderToStaticStream(): The streaming API is not available ' +
66
+ 'in the browser. Use ReactDOMServer.renderToStaticMarkup() instead.',
67
+ );
68
+ });
69
+ }
70
+});