This document describes react-static, a tool for building static sites with React. It outlines the problems react-static aims to solve:
1. Define the structure of pages and render React components to HTML files
2. Bundle client-side JavaScript and provide instant page linking via React Router
3. Include a development server that watches for changes and reloads automatically
It then details how react-static implements solutions to these problems using React, React Router, fs-promise for rendering to files, browserify for bundling JavaScript, and nodemon/Express for the dev server. Finally, it encourages finding ways to improve react-static or build your own static site generator.
21. 21
import { match, RoutingContext } from ‘react-router';
import routes from '../src/components/routes';
/*
* For the `indexRoute` plus all
* `childRoutes`, do the following
*/
const location = '/'.concat(path || '');
match(
{ routes, location },
async function handleMatch(err, redirectLocation, renderProps) {
/*
* Render component markup, create output directories
* and write markup to a file whose filename is
* extracted from the route's path.
* Provide fallback of `index.html` for IndexRoute.
*/
}
);
match each location
22. 22
import { exec } from 'child_process';
import React from 'react';
import { renderToString } from ‘react-dom/server';
import fsp from ‘fs-promise';
const html = renderToString(<RoutingContext {...renderProps} />),
directory = determineDirectory(path),
filePath = path || 'index.html';
await exec(`mkdir -p _site/${directory}`, execCallback);
await fsp.writeFile(
`_site/${filePath}`,
`<!DOCTYPE html>${componentHTML}`,
'utf8',
fspCallback
);
render react and write files
23. 23
1. define structure
of pages
2. create HTML files
from rendered
react
3. bundle client-side
JS and provide
instant page linking
36. 36
1. create CLI
3. dev server that
watches and reloads
2. copy file structure
defaults to consumer
37. 37
#!/usr/bin/env node
import program from ‘commander';
program
.command('new [path]')
.description('create a new react-static project')
.action(function handleNew(path, options) {
if (path) {
// copy over defaults
} else {
// handle no path
}
});
$ react-static new portfolio/
38. 38
1. create CLI
3. dev server that
watches and reloads
2. copy file structure
defaults to consumer
40. 40
program
.command('serve')
.description('run the dev server and have it watch for changes')
.action(function handleServe() {
execSync('node_modules/.bin/nodemon', { stdio: [0,1,2] });
});
$ react-static serve
// build HTML & JS & then...
const app = express();
app.use('/', express.static('_site'));
app.listen(port);
console.log(`=> A development server is running at http://
localhost:${port}`);