Files: 1b77a91b5043f96c866edfed9022577b95e3c14f / app / render.js
2505 bytesRaw
1 | // https://github.com/jlongster/react-redux-universal-hot-example/blob/master/src/server.js |
2 | |
3 | import http from 'http' |
4 | import Url from 'url' |
5 | import React from 'react' |
6 | import { renderToString } from 'react-dom/server' |
7 | import { Provider } from 'react-redux' |
8 | import { Router, RouterContext, match, createMemoryHistory as createHistory } from 'react-router' |
9 | import sendHtml from 'send-data/html' |
10 | import sendError from 'send-data/error' |
11 | import redirect from 'predirect' |
12 | |
13 | import createStore from 'app/store' |
14 | import createRoutes from 'app/routes' |
15 | import fetchAllData from 'app/util/fetch-all-data' |
16 | |
17 | export function createServer (config) { |
18 | const staticUrl = Url.format(config.static.url) |
19 | |
20 | return http.createServer(render) |
21 | |
22 | function render (req, res) { |
23 | const history = createHistory() |
24 | const store = createStore(undefined, history) |
25 | |
26 | match({ |
27 | routes: createRoutes(store), |
28 | location: req.url |
29 | }, function (err, redirectLocation, renderProps) { |
30 | if (redirectLocation) { |
31 | redirect(req, res, redirectLocation.pathname + redirectLocation.search) |
32 | } else if (err) { |
33 | sendError(req, res, { body: err }) |
34 | } else if (!renderProps) { |
35 | sendError(req, res, { |
36 | statusCode: 404, |
37 | body: new Error('Not found') |
38 | }) |
39 | } else { |
40 | fetchAllData( |
41 | renderProps.components, |
42 | store.getState, store.dispatch, |
43 | renderProps.location, |
44 | renderProps.params |
45 | ).then(function () { |
46 | const component = <Provider store={store}> |
47 | <RouterContext { ...renderProps } /> |
48 | </Provider> |
49 | |
50 | var innerHtml |
51 | try { |
52 | innerHtml = renderToString(component) |
53 | } catch (err) { |
54 | return sendError(req, res, { body: err }) |
55 | } |
56 | |
57 | const html = renderFullPage(innerHtml, store.getState(), config) |
58 | |
59 | sendHtml(req, res, html) |
60 | }) |
61 | } |
62 | }) |
63 | } |
64 | |
65 | function renderFullPage (innerHtml, initialData) { |
66 | return ` |
67 | <!DOCTYPE html> |
68 | <html lang="en"> |
69 | <head> |
70 | <meta charset="utf-8" /> |
71 | <title>Craftworks TodoMVC</title> |
72 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
73 | </head> |
74 | <body> |
75 | <main>${ innerHtml }</main> |
76 | <script> |
77 | window.__data = ${ JSON.stringify(initialData) } |
78 | </script> |
79 | <script src="${Url.resolve(staticUrl, 'bundle.js')}"></script> |
80 | </body> |
81 | </html> |
82 | ` |
83 | } |
84 | } |
85 | |
86 |
Built with git-ssb-web