Add documentation

This commit is contained in:
Kimmo Puputti 2017-01-09 11:54:38 +02:00
parent 53903cef70
commit ba3418c661
3 changed files with 48 additions and 1 deletions

View file

@ -1,3 +1,19 @@
/**
* This is the main server to run the production application.
*
* Running the server requires that `npm run build` is run so that the
* production JS bundle can be imported.
*
* This server renders the requested URL in the server side for
* performance, SEO, etc., and properly handles redirects, HTTP status
* codes, and serving the static assets.
*
* When the application is loaded in a browser, the client side app
* takes control and all the functionality such as routing is handled
* in the client.
*/
// This enables nice stacktraces from the minified production bundle
require('source-map-support').install();
const express = require('express');
@ -7,15 +23,21 @@ const _ = require('lodash');
const React = require('react');
const { createServerRenderContext } = require('react-router');
// Construct the bundle path where the server side renering function
// can be imported.
const buildPath = path.resolve(__dirname, '..', 'build');
const manifestPath = path.join(buildPath, 'asset-manifest.json');
const manifest = require(manifestPath);
const mainJsPath = path.join(buildPath, manifest['main.js']);
const renderApp = require(mainJsPath).default;
// The HTML build file is generated from the `public/index.html` file
// and used as a template for server side rendering. The application
// head and body are injected to the template from the results of
// calling the `renderApp` function imported from the bundle above.
const indexHtml = fs.readFileSync(path.join(buildPath, 'index.html'), 'utf-8');
const reNoMatch = /($^)/;
const reNoMatch = /($^)/;
const template = _.template(indexHtml, {
// Interpolate variables in the HTML template with the following

View file

@ -2,6 +2,8 @@ import React from 'react';
import { Match, Miss, Redirect } from 'react-router';
import { HomePage, SearchPage, NotFoundPage } from './containers';
// This is only used for testing that redirects work correct in the
// client and when rendering in the server.
const RedirectTestPage = () => (
<Redirect to="/" />
);

View file

@ -1,3 +1,14 @@
/**
* This is the main entrypoint file for the application.
*
* When loaded in the client side, the application is rendered in the
* #root element.
*
* When the bundle created from this file is imported in the server
* side, the exported `renderApp` function can be used for server side
* rendering.
*/
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOMServer from 'react-dom/server';
@ -21,10 +32,21 @@ const ServerApp = (props) => {
);
};
// If we're in a browser already, render the client application.
if (typeof window !== 'undefined') {
ReactDOM.render(<ClientApp />, document.getElementById('root'));
}
/**
* Render the given route.
*
* @param {String} url Path to render
* @param {Object} serverContext Server rendering context from react-router
*
* @returns {Object} Object with keys:
* - {String} body: Rendered application body of the given route
* - {Object} head: Application head metadata from react-helmet
*/
const renderApp = (url, serverContext) => {
const body = ReactDOMServer.renderToString(
<ServerApp url={ url } context={ serverContext }/>
@ -33,4 +55,5 @@ const renderApp = (url, serverContext) => {
return { head, body };
};
// Export the function for server side rendering.
export default renderApp;