Skip to content

Commit cc3bffd

Browse files
committed
frontend: update to use found-relay and server-side rendering
Referencing implementation in https://github.com/relay-tools/found-relay/tree/master/examples/todomvc-universal Also upgraded to newer relay and babel libraries.
1 parent ce217f7 commit cc3bffd

30 files changed

+3627
-2470
lines changed

frontend/.babelrc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"passPerPreset": true,
33
"plugins": [
44
["relay", { "artifactDirectory": "./ts/__relay_artifacts__" }],
5-
"transform-runtime"
5+
"@babel/plugin-transform-runtime",
6+
"@babel/plugin-proposal-class-properties"
67
],
78
"presets": [
8-
"react",
9-
"es2015",
10-
"stage-0"
9+
"@babel/preset-react",
10+
"@babel/preset-env"
1111
]
1212
}

frontend/package.json

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,56 @@
1313
"trailingComma": "all"
1414
},
1515
"dependencies": {
16-
"@babel/core": "^7.0.0-0",
17-
"babel-core": "^6.26.0",
18-
"babel-loader": "^7.1.2",
19-
"babel-plugin-relay": "^9.0.0",
20-
"babel-plugin-transform-runtime": "^6.12.0",
21-
"babel-preset-es2015": "^6.13.2",
22-
"babel-preset-react": "^6.11.1",
23-
"babel-preset-stage-0": "^6.5.0",
16+
"@babel/core": "^7.11.0",
17+
"@babel/plugin-transform-runtime": "^7.11.0",
18+
"@babel/register": "^7.10.5",
19+
"babel-loader": "^8.1.0",
20+
"babel-plugin-relay": "^10.0.1",
2421
"babel-runtime": "^6.26.0",
2522
"classnames": "2.2.5",
23+
"copy-webpack-plugin": "^6.0.3",
2624
"express": "^4.15.2",
27-
"graphql": "^14.5.8",
25+
"farce": "^0.4.4",
26+
"found": "^0.5.7",
27+
"found-relay": "^0.8.2",
28+
"graphql": "^15.3.0",
2829
"graphql-compiler": "^1.7.0",
2930
"graphql-relay": "^0.6.0",
31+
"http-proxy-middleware": "^1.0.5",
32+
"isomorphic-fetch": "^2.2.1",
3033
"prop-types": "^15.6.2",
31-
"react": "^16.10.2",
34+
"react": "^16.13.1",
3235
"react-dom": "^16.10.2",
33-
"react-relay": "^9.0.0",
34-
"relay-runtime": "^9.0.0",
36+
"react-relay": "^10.0.1",
37+
"react-relay-network-modern": "^4.7.4",
38+
"react-relay-network-modern-ssr": "^1.4.0",
39+
"relay-runtime": "^10.0.1",
3540
"todomvc-app-css": "^2.1.0",
3641
"todomvc-common": "^1.0.3",
37-
"webpack": "^4.41.2",
38-
"webpack-dev-server": "^3.1.11",
39-
"whatwg-fetch": "2.0.3"
42+
"webpack": "^4.44.1",
43+
"webpack-dev-server": "^3.11.0"
4044
},
4145
"devDependencies": {
42-
"@types/node": "^12.11.7",
43-
"@types/prop-types": "^15.5.5",
44-
"@types/react": "^16.4.12",
45-
"@types/react-dom": "^16.0.7",
46-
"@types/react-relay": "^7.0.3",
47-
"@types/relay-runtime": "^6.0.8",
48-
"babel-cli": "^6.26.0",
49-
"babel-eslint": "6.1.2",
50-
"csstype": "^2.5.6",
51-
"fork-ts-checker-webpack-plugin": "^3.1.1",
52-
"relay-compiler": "^8.0.0",
53-
"relay-compiler-language-typescript": "^12.0.4",
54-
"ts-loader": "^6.2.0",
55-
"tslint": "^5.20.0",
46+
"@babel/node": "^7.10.5",
47+
"@babel/plugin-proposal-class-properties": "^7.10.4",
48+
"@babel/preset-env": "^7.11.0",
49+
"@babel/preset-react": "^7.10.4",
50+
"@babel/preset-typescript": "^7.10.4",
51+
"@types/node": "^14.0.27",
52+
"@types/prop-types": "^15.7.3",
53+
"@types/react": "^16.9.44",
54+
"@types/react-dom": "^16.9.8",
55+
"@types/react-relay": "^7.0.8",
56+
"@types/relay-runtime": "^10.0.1",
57+
"babel-eslint": "^10.1.0",
58+
"csstype": "^3.0.2",
59+
"fork-ts-checker-webpack-plugin": "^5.0.13",
60+
"relay-compiler": "^10.0.1",
61+
"relay-compiler-language-typescript": "^13.0.0",
62+
"ts-loader": "^8.0.2",
63+
"tslint": "^6.1.3",
5664
"tslint-plugin-relay": "^0.0.3",
57-
"typescript": "^3.6.3"
65+
"typescript": "^3.9.7"
5866
},
5967
"proxy": "http://localhost:5000"
6068
}

frontend/server.js

Lines changed: 113 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,48 @@
1010
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1111
*/
1212

13+
require('@babel/register')( {
14+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
15+
presets: [
16+
"@babel/preset-env",
17+
"@babel/preset-react",
18+
"@babel/preset-typescript",
19+
],
20+
plugins: [
21+
["@babel/plugin-transform-runtime",
22+
{
23+
"regenerator": true
24+
}
25+
]
26+
]
27+
} )
28+
import 'isomorphic-fetch';
29+
30+
import CopyWebpackPlugin from 'copy-webpack-plugin';
1331
import express from 'express';
14-
import path from 'path';
32+
import { createProxyMiddleware } from 'http-proxy-middleware';
33+
import { Resolver } from 'found-relay';
34+
import { getFarceResult } from 'found/server';
35+
import ReactDOMServer from 'react-dom/server';
36+
import RelayServerSSR from 'react-relay-network-modern-ssr/lib/server';
37+
import serialize from 'serialize-javascript';
1538
import webpack from 'webpack';
16-
import WebpackDevServer from 'webpack-dev-server';
39+
import webpackMiddleware from 'webpack-dev-middleware';
40+
import path from 'path';
1741
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
1842

43+
const { createRelayEnvironment } = require('./ts/createRelayEnvironment')
44+
const { historyMiddlewares, routeConfig } = require('./ts/router')
45+
1946
const APP_PORT = 3000;
2047
const GRAPHQL_PORT = 5000;
2148

22-
// Serve the Relay app
23-
const compiler = webpack({
24-
entry: ['whatwg-fetch', path.resolve(__dirname, 'ts', 'app.tsx')],
49+
const app = express();
50+
51+
const webpackConfig = {
52+
mode: 'development',
53+
54+
entry: ['isomorphic-fetch', path.resolve(__dirname, 'ts', 'client.tsx')],
2555
resolve: {
2656
extensions: ['.ts', '.tsx', '.js'],
2757
},
@@ -37,19 +67,87 @@ const compiler = webpack({
3767
},
3868
],
3969
},
70+
output: {filename: 'app.js', path: '/'},
4071
plugins: [
4172
new ForkTsCheckerWebpackPlugin(),
73+
new CopyWebpackPlugin({
74+
patterns: [
75+
'public/learn.json',
76+
'node_modules/todomvc-common/base.css',
77+
'node_modules/todomvc-app-css/index.css',
78+
],
79+
}),
4280
],
43-
output: {filename: 'app.js', path: '/'},
44-
});
45-
const app = new WebpackDevServer(compiler, {
46-
contentBase: '/public/',
47-
proxy: {'/graphql': `http://localhost:${GRAPHQL_PORT}`},
48-
publicPath: '/js/',
49-
stats: {colors: true},
81+
82+
devtool: 'cheap-module-source-map',
83+
};
84+
85+
app.use(
86+
webpackMiddleware(webpack(webpackConfig), {
87+
stats: { colors: true },
88+
}),
89+
);
90+
91+
const options = {
92+
target: `http://localhost:${GRAPHQL_PORT}`,
93+
changeOrigin: true, // needed for virtual hosted sites
94+
ws: true, // proxy websockets
95+
pathRewrite: {
96+
},
97+
router: function(req) {
98+
return {
99+
protocol: 'http:',
100+
host: 'localhost',
101+
port: GRAPHQL_PORT,
102+
}
103+
},
104+
};
105+
app.use('/graphql', createProxyMiddleware('/graphql', options))
106+
107+
app.use(async (req, res) => {
108+
const relaySsr = new RelayServerSSR();
109+
110+
const { redirect, status, element } = await getFarceResult({
111+
url: req.url,
112+
historyMiddlewares,
113+
routeConfig,
114+
resolver: new Resolver(
115+
createRelayEnvironment(relaySsr, `http://localhost:${GRAPHQL_PORT}/graphql`),
116+
),
117+
});
118+
119+
if (redirect) {
120+
res.redirect(302, redirect.url);
121+
return;
122+
}
123+
124+
const appHtml = ReactDOMServer.renderToString(element);
125+
const relayData = await relaySsr.getCache();
126+
127+
res.status(status).send(`
128+
<!DOCTYPE html>
129+
<html>
130+
131+
<head>
132+
<meta charset="utf-8">
133+
<title>Relay • TodoMVC</title>
134+
<link rel="stylesheet" href="base.css">
135+
<link rel="stylesheet" href="index.css">
136+
</head>
137+
138+
<body>
139+
<div id="root">${appHtml}</div>
140+
141+
<script>
142+
window.__RELAY_PAYLOADS__ = ${serialize(relayData, { isJSON: true })};
143+
</script>
144+
<script src="/app.js"></script>
145+
</body>
146+
147+
</html>
148+
`);
50149
});
51-
// Serve static resources
52-
app.use('/', express.static(path.resolve(__dirname, 'public')));
150+
53151
app.listen(APP_PORT, () => {
54-
console.log(`App is now running on http://localhost:${APP_PORT}`);
152+
console.log(`listening on port ${APP_PORT}`); // eslint-disable-line no-console
55153
});

0 commit comments

Comments
 (0)