main
js 95 lines 2.22 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 */
8
9 'use strict';
10
11 const babelRegister = require('@babel/register');
12 babelRegister({
13 ignore: [/[\\\/](build|server\/server|node_modules)[\\\/]/],
14 presets: [['react-app', {runtime: 'automatic'}]],
15 plugins: ['@babel/transform-modules-commonjs'],
16 });
17
18 const express = require('express');
19 const compress = require('compression');
20 const {readFileSync} = require('fs');
21 const path = require('path');
22 const render = require('./render');
23 const {JS_BUNDLE_DELAY} = require('./delays');
24
25 const PORT = process.env.PORT || 4000;
26 const app = express();
27
28 app.use((req, res, next) => {
29 if (req.url.endsWith('.js')) {
30 // Artificially delay serving JS
31 // to demonstrate streaming HTML.
32 setTimeout(next, JS_BUNDLE_DELAY);
33 } else {
34 next();
35 }
36 });
37
38 app.use(compress());
39 app.get(
40 '/',
41 handleErrors(async function (req, res) {
42 await waitForWebpack();
43 render(req.url, res);
44 })
45 );
46 app.use(express.static('build'));
47 app.use(express.static('public'));
48
49 app
50 .listen(PORT, () => {
51 console.log(`Listening at ${PORT}...`);
52 })
53 .on('error', function (error) {
54 if (error.syscall !== 'listen') {
55 throw error;
56 }
57 const isPipe = portOrPipe => Number.isNaN(portOrPipe);
58 const bind = isPipe(PORT) ? 'Pipe ' + PORT : 'Port ' + PORT;
59 switch (error.code) {
60 case 'EACCES':
61 console.error(bind + ' requires elevated privileges');
62 process.exit(1);
63 break;
64 case 'EADDRINUSE':
65 console.error(bind + ' is already in use');
66 process.exit(1);
67 break;
68 default:
69 throw error;
70 }
71 });
72
73 function handleErrors(fn) {
74 return async function (req, res, next) {
75 try {
76 return await fn(req, res);
77 } catch (x) {
78 next(x);
79 }
80 };
81 }
82
83 async function waitForWebpack() {
84 while (true) {
85 try {
86 readFileSync(path.resolve(__dirname, '../build/main.js'));
87 return;
88 } catch (err) {
89 console.log(
90 'Could not find webpack build output. Will retry in a second...'
91 );
92 await new Promise(resolve => setTimeout(resolve, 1000));
93 }
94 }
95 }