server.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. var express = require('express');
  2. var path = require('path');
  3. var compression = require('compression');
  4. import React from 'react';
  5. import { renderToString } from 'react-dom/server';
  6. import { match, RouterContext } from 'react-router';
  7. import routes from './modules/routes';
  8. var app = express();
  9. app.use(compression());
  10. // serve our static stuff like index.css
  11. app.use(express.static(path.join(__dirname, 'public')));
  12. // Send all requests to index.html so browserHistory in React Router works
  13. app.get('*', (req, res) => {
  14. match({ routes, location: req.url }, (err, redirect, props) => {
  15. console.log(`SSR for ${req.url}`);
  16. // in here we can make some decisions all at once
  17. if (err) {
  18. // there was an error somewhere during route matching
  19. res.status(500).send(err.message);
  20. } else if (redirect) {
  21. // we haven't talked about `onEnter` hooks on routes, but before a
  22. // route is entered, it can redirect. Here we handle on the server.
  23. res.redirect(redirect.pathname + redirect.search);
  24. } else if (props) {
  25. // if we got props then we matched a route and can render
  26. // `RouterContext is what the `Router` renders. `Router` keeps these `props`
  27. // in its state as it listens to `browserHistory`. But on the server, our
  28. // app is stateless, so we need to use `match` to get these props before
  29. // rendering.
  30. const appHtml = renderToString(<RouterContext { ...props } />);
  31. // Dump the HTML into a template, lots of ways to do this, but none are
  32. // really influenced by React Router, so we're just using a little function,
  33. // `renderPage`.
  34. res.send(renderPage(appHtml));
  35. } else {
  36. // no errors, no redirect, we just didn't match anything
  37. res.status(404).send("Not found");
  38. }
  39. });
  40. });
  41. function renderPage(appHtml) {
  42. return `
  43. <!DOCTYPE HTML>
  44. <html>
  45. <head>
  46. <meta charset="utf-8" />
  47. <title>My first React Router App</title>
  48. <link rel="stylesheet" href="/index.css" />
  49. </head>
  50. <body>
  51. <div id="app">${appHtml}</div>
  52. <script src="/bundle.js"></script>
  53. </body>
  54. </html>
  55. `;
  56. }
  57. var PORT = process.env.PORT || 8080;
  58. app.listen(PORT, function () {
  59. console.log('"Production" Express server running at localhost:' + PORT);
  60. });