[Flight Fixture] Server + Client Components (#20150)
Dan Abramov committed
Nov 3, 2020 at 03:00 UTC
2af07d3f4d3b5bf5d34b66d1bd64c9b521713125
6 files changed
+49
-38
fixtures/flight/server/App.server.js
new
+16
@@ -0,0 +1,16 @@
1
+import * as React from 'react';
2
+
3
+// TODO: A transform should read this from webpack plugin output.
4
+const CounterClient = {
5
+ $$typeof: Symbol.for('react.module.reference'),
6
+ name: './src/Counter.client.js',
7
+};
8
+
9
+export default function App() {
10
+ return (
11
+ <div>
12
+ <h1>Hello, world</h1>
13
+ <CounterClient />
14
+ </div>
15
+ );
16
+}
fixtures/flight/server/handler.js
+11
-20
@@ -1,26 +1,17 @@
1
'use strict';
2
3
-const ReactTransportDOMServer = require('react-transport-dom-webpack/server');
4
-const React = require('react');
5
-const Stream = require('stream');
6
-
7
-function Text({children}) {
8
- return <span>{children}</span>;
9
-}
10
-
11
-function HTML() {
12
- return (
13
- <div>
14
- <Text>Hello</Text>
15
- <Text>world</Text>
16
- </div>
17
- );
18
-}
3
+import {pipeToNodeWritable} from 'react-transport-dom-webpack/server';
4
+import * as React from 'react';
5
+import App from './App.server';
6
7
module.exports = function(req, res) {
8
res.setHeader('Access-Control-Allow-Origin', '*');
22
- let model = {
23
- content: <HTML />,
24
- };
25
- ReactTransportDOMServer.pipeToNodeWritable(model, res);
9
+ pipeToNodeWritable(<App />, res, {
10
+ // TODO: Read from a map on the disk.
11
+ './src/Counter.client.js': {
12
+ id: './src/Counter.client.js',
13
+ chunks: ['2'],
14
+ name: 'default',
15
+ },
16
+ });
17
};
fixtures/flight/server/index.js
+1
@@ -5,6 +5,7 @@ const babelRegister = require('@babel/register');
5
babelRegister({
6
ignore: [/\/(build|node_modules)\//],
7
presets: ['react-app'],
8
+ plugins: ['@babel/transform-modules-commonjs'],
9
});
10
11
const express = require('express');
fixtures/flight/src/App.js
deleted
-15
@@ -1,15 +0,0 @@
1
-import React, {Suspense} from 'react';
2
-
3
-function Content({data}) {
4
- return data.readRoot().content;
5
-}
6
-
7
-function App({data}) {
8
- return (
9
- <Suspense fallback={<h1>Loading...</h1>}>
10
- <Content data={data} />
11
- </Suspense>
12
- );
13
-}
14
-
15
-export default App;
fixtures/flight/src/Counter.client.js
new
+6
@@ -0,0 +1,6 @@
1
+import * as React from 'react';
2
+
3
+export default function Counter() {
4
+ const [count, setCount] = React.useState(0);
5
+ return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>;
6
+}
fixtures/flight/src/index.js
+15
-3
@@ -1,10 +1,22 @@
1
-import React from 'react';
1
+import React, {Suspense} from 'react';
2
import ReactDOM from 'react-dom';
3
import ReactTransportDOMClient from 'react-transport-dom-webpack';
4
-import App from './App';
4
5
let data = ReactTransportDOMClient.createFromFetch(
6
fetch('http://localhost:3001')
7
);
8
10
-ReactDOM.render(<App data={data} />, document.getElementById('root'));
9
+function Content() {
10
+ return data.readRoot();
11
+}
12
+
13
+ReactDOM.render(
14
+ <Suspense fallback={<h1>Loading...</h1>}>
15
+ <Content />
16
+ </Suspense>,
17
+ document.getElementById('root')
18
+);
19
+
20
+// Create entry points for Client Components.
21
+// TODO: Webpack plugin should do this and write a map to disk.
22
+require.context('./', true, /\.client\.js$/, 'lazy');