main
js 108 lines 2.54 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 renderToString = require('./render-to-string');
23 const renderToStream = require('./render-to-stream');
24 const renderToBuffer = require('./render-to-buffer');
25 const {JS_BUNDLE_DELAY} = require('./delays');
26
27 const PORT = process.env.PORT || 4000;
28 const app = express();
29
30 app.use(compress());
31 app.get(
32 '/',
33 handleErrors(async function (req, res) {
34 await waitForWebpack();
35 renderToStream(req.url, res);
36 })
37 );
38 app.get(
39 '/string',
40 handleErrors(async function (req, res) {
41 await waitForWebpack();
42 renderToString(req.url, res);
43 })
44 );
45 app.get(
46 '/stream',
47 handleErrors(async function (req, res) {
48 await waitForWebpack();
49 renderToStream(req.url, res);
50 })
51 );
52 app.get(
53 '/buffer',
54 handleErrors(async function (req, res) {
55 await waitForWebpack();
56 renderToBuffer(req.url, res);
57 })
58 );
59 app.use(express.static('build'));
60 app.use(express.static('public'));
61
62 app
63 .listen(PORT, () => {
64 console.log(`Listening at ${PORT}...`);
65 })
66 .on('error', function (error) {
67 if (error.syscall !== 'listen') {
68 throw error;
69 }
70 const isPipe = portOrPipe => Number.isNaN(portOrPipe);
71 const bind = isPipe(PORT) ? 'Pipe ' + PORT : 'Port ' + PORT;
72 switch (error.code) {
73 case 'EACCES':
74 console.error(bind + ' requires elevated privileges');
75 process.exit(1);
76 break;
77 case 'EADDRINUSE':
78 console.error(bind + ' is already in use');
79 process.exit(1);
80 break;
81 default:
82 throw error;
83 }
84 });
85
86 function handleErrors(fn) {
87 return async function (req, res, next) {
88 try {
89 return await fn(req, res);
90 } catch (x) {
91 next(x);
92 }
93 };
94 }
95
96 async function waitForWebpack() {
97 while (true) {
98 try {
99 readFileSync(path.resolve(__dirname, '../build/main.js'));
100 return;
101 } catch (err) {
102 console.log(
103 'Could not find webpack build output. Will retry in a second...'
104 );
105 await new Promise(resolve => setTimeout(resolve, 1000));
106 }
107 }
108 }