56 lines
1.6 KiB
JavaScript
56 lines
1.6 KiB
JavaScript
import path from 'path';
|
|
import { Server } from 'http';
|
|
import Express from 'express';
|
|
import React from 'react';
|
|
import { renderToString } from 'react-dom/server';
|
|
import { match, RouterContext } from 'react-router';
|
|
import routes from './routes';
|
|
import NotFoundPage from './components/NotFoundPage';
|
|
|
|
// initialize the server and configure support for ejs templates
|
|
const app = new Express();
|
|
const server = new Server(app);
|
|
app.set('view engine', 'ejs');
|
|
app.set('views', path.join(__dirname, '..', 'views'));
|
|
|
|
// define the folder that will be used for public assets
|
|
app.use(Express.static(path.join(__dirname, '..', 'public')));
|
|
|
|
// universal routing and rendering
|
|
app.get('*', (req, res) => {
|
|
match({routes, location: req.url}, (err, redirectLocation, renderProps) => {
|
|
// Directly send errors
|
|
if (err) {
|
|
return res.status(500).send(err.message);
|
|
}
|
|
|
|
// Propagate redirects to the browser
|
|
if (redirectLocation) {
|
|
return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
|
|
}
|
|
|
|
// generate the React markup for the current route
|
|
let markup;
|
|
if (renderProps) {
|
|
// if the current route matched, we have renderProps
|
|
markup = renderToString(<RouterContext {...renderProps} />);
|
|
} else {
|
|
markup = renderToString(<NotFoundPage />);
|
|
res.status(404);
|
|
}
|
|
|
|
// render the index template with the embedded React markup
|
|
return res.render('index', { markup:markup });
|
|
});
|
|
});
|
|
|
|
// start the server
|
|
const port = process.env.PORT || 3000;
|
|
const env = process.env.NODE_ENV || 'production';
|
|
|
|
server.listen(port, err => {
|
|
if (err) {
|
|
return console.error(err);
|
|
}
|
|
console.info(`Server running on http://localhost:${port} [${env}]`);
|
|
}); |