diff --git a/docs/.eslintrc b/docs/.eslintrc
index dc65dd4c40..87ac3840ba 100644
--- a/docs/.eslintrc
+++ b/docs/.eslintrc
@@ -3,5 +3,8 @@
"comma-spacing": 0,
"react/no-multi-comp": 0,
"react/prop-types": 0
+ },
+ "globals": {
+ "CodeMirror": true
}
}
diff --git a/docs/README.md b/docs/README.md
index 3d071c5440..a6c53990ea 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -11,10 +11,26 @@ Pages](http://pages.github.com/).
From the repository root run `npm run docs` and navigate your browser to
`http://localhost:4000`. This will start an express base node server with
webpack-dev middleware that will watch your file changes and recompile all the
-static assets needed to generate the site.
+static assets needed to generate the site. In the console output you'll see that
+we bind to two ports. The first port is the one you'll use to load the docs in
+your browser. The second is the webpack-dev-server we use to build the client
+side assets in watch mode. _Note: while the docs should start on port 4000 if
+that port is in use we progressively look for an available port. Observe
+console output for the actual port that we use._ We use the
+[webpack][webpack-hot] and [react][react-hot] hot loading functionality to allow
+your development experience to have quickest feedback loop possible.
+
+For a demo of how the hot loader works checkout this video:
+
+
## Production
This site is statically published on github pages, to do this the static assets
need to be generated. You can simulate a similar experience with `npm run
docs-prod` and navigating your browser to `http://localhost:4000`
+
+[webpack-hot]: http://webpack.github.io/docs/hot-module-replacement-with-webpack.html
+[react-hot]: http://gaearon.github.io/react-hot-loader/
diff --git a/docs/src/CodeMirror.css b/docs/assets/CodeMirror.css
similarity index 100%
rename from docs/src/CodeMirror.css
rename to docs/assets/CodeMirror.css
diff --git a/docs/client.js b/docs/client.js
index 0fb9d754f5..0bf1bb699e 100644
--- a/docs/client.js
+++ b/docs/client.js
@@ -6,10 +6,18 @@ import './assets/carousel.png';
import './assets/logo.png';
import './assets/favicon.ico';
+import 'codemirror/mode/javascript/javascript';
+import 'codemirror/theme/solarized.css';
+import 'codemirror/lib/codemirror.css';
+import './assets/CodeMirror.css';
+
import React from 'react';
+import CodeMirror from 'codemirror';
import Router from 'react-router';
import routes from './src/Routes';
+global.CodeMirror = CodeMirror;
+
Router.run(routes, Router.RefreshLocation, Handler => {
React.render(
React.createElement(Handler, window.INITIAL_PROPS), document);
diff --git a/docs/dev-run b/docs/dev-run
index 24fe49d995..8eed9789d1 100755
--- a/docs/dev-run
+++ b/docs/dev-run
@@ -7,8 +7,7 @@ import { exec } from 'child-process-promise';
portfinder.basePort = 4000;
const SIGINT = 'SIGINT';
-let webpackDevServer;
-let docsServer;
+let processMap = {};
function output(prefix, message) {
let formattedMessage = message.trim().split('\n')
@@ -23,22 +22,37 @@ function listen({stdout, stderr}, name) {
}
function shutdown() {
- if (webpackDevServer) {
- webpackDevServer.kill(SIGINT);
- }
- if (docsServer) {
- docsServer.kill(SIGINT);
+ for (let key in processMap) {
+ processMap[key].kill(SIGINT);
}
}
function catchExec(name, err) {
if (err.killed) {
console.log('Shutdown: '.cyan + name.green);
- } else {
- console.log(`${name} -- Failed`.red);
- console.log(err.toString().red);
+ shutdown();
+ return false;
}
- shutdown();
+
+ console.log(`${name} -- Failed`.red);
+ console.log(err.toString().red);
+ return true;
+}
+
+function runCmd(name, cmd, options) {
+ exec(cmd, options)
+ .progress(childProcess => {
+ listen(childProcess, name);
+ processMap[name] = childProcess;
+ return;
+ })
+ .then(() => console.log('Shutdown: '.cyan + name.green))
+ .catch(err => {
+ if (catchExec(name, err)) {
+ // Restart if not explicitly shutdown
+ runCmd(name, cmd, options);
+ }
+ });
}
console.log('Starting docs in Development mode'.cyan);
@@ -51,28 +65,14 @@ portfinder.getPorts(2, {}, (portFinderErr, [docsPort, webpackPort]) => {
process.exit(1);
}
- exec(`webpack-dev-server --quiet --config webpack.docs.js --color --port ${webpackPort}`)
- .progress(childProcess => {
- listen(childProcess, 'webpack-dev-server');
- webpackDevServer = childProcess;
- return;
- })
- .then(() => console.log('Shutdown: '.cyan + 'webpack-dev-server'.green))
- .catch(err => catchExec('webpack-dev-server', err));
+ runCmd('webpack-dev-server', `nodemon --watch webpack --watch webpack.config.js --watch node_modules --exec webpack-dev-server -- --config webpack.docs.js --color --port ${webpackPort} --debug --hot`);
- exec('nodemon --exec babel-node docs/server.js', {
- env: {
- PORT: docsPort,
- WEBPACK_DEV_PORT: webpackPort,
- ...process.env
- }
- })
- .progress(childProcess => {
- listen(childProcess, 'docs-server');
- docsServer = childProcess;
- return;
- })
- .then(() => console.log('Shutdown: '.cyan + 'docs-server'.green))
- .catch(err => catchExec('docs-server', err));
+ runCmd('docs-server', 'nodemon --watch docs --watch src --watch node_modules --exec babel-node docs/server.js', {
+ env: {
+ PORT: docsPort,
+ WEBPACK_DEV_PORT: webpackPort,
+ ...process.env
+ }
+ });
});
diff --git a/docs/server.js b/docs/server.js
index 2554a5482a..78918d8452 100644
--- a/docs/server.js
+++ b/docs/server.js
@@ -21,8 +21,11 @@ if (development) {
});
app.use(function renderApp(req, res) {
+ res.header('Access-Control-Allow-Origin', target);
+ res.header('Access-Control-Allow-Headers', 'X-Requested-With');
+
Router.run(routes, req.url, Handler => {
- let html = React.renderToString(