From 4dd324786117cf49829c6e7135c7b20fab71b8bf Mon Sep 17 00:00:00 2001 From: Sresan Thevarajah Date: Mon, 10 Oct 2016 23:12:26 -0700 Subject: [PATCH 1/5] Provide hook for custom middleware setup --- docs/guides/react-server-cli.md | 13 +++++++ .../react-server-cli/src/commands/start.js | 36 +++++++++++++++---- packages/react-server-cli/src/parseCliArgs.js | 5 +++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/guides/react-server-cli.md b/docs/guides/react-server-cli.md index d3eabbe1c..d7b3504be 100755 --- a/docs/guides/react-server-cli.md +++ b/docs/guides/react-server-cli.md @@ -114,8 +114,21 @@ export default (webpackConfig) => { In the `.reactserverrc` file add an option for `webpack-config` that points to that function file and when React Server is setting up Webpack it will call your function with the result of the built in Webpack options, allowing you to make any modifications needed. +### Use Custom Express Middleware +React Server currently the default Express Middlewares used are compression, body-parser, cookie-parser and of course react-server. If you need to setup custom express middleware you can do it with a setup function. + +```javascript +export default (server, reactServerMiddleware) => { + server.use(compression()); + server.use(bodyParser.urlencoded({ extended: false })); + server.use(bodyParser.json()); + server.use(session(options)); + rsMiddleware(); // Must be called once or server will not start +} +``` +In the `.reactserverrc` file add an option for `custom-middleware-path` that points to that function file and when React Server is setting up the server it will call your function for setup rather then the default middlewares mentioned above. On the command line the option is `--custom-middleware-path`. ### Development mode: making a great DX diff --git a/packages/react-server-cli/src/commands/start.js b/packages/react-server-cli/src/commands/start.js index c4819c467..730dccfb0 100644 --- a/packages/react-server-cli/src/commands/start.js +++ b/packages/react-server-cli/src/commands/start.js @@ -1,5 +1,6 @@ import http from "http" import https from "https" +import path from "path" import express from "express" import compression from "compression" import bodyParser from "body-parser" @@ -28,6 +29,7 @@ export default function start(options){ jsUrl, httpsOptions, longTermCaching, + customMiddlewarePath, } = options; const {serverRoutes, compiler} = compileClient(options); @@ -46,7 +48,7 @@ export default function start(options){ logger.notice("Starting servers...") const jsServer = startJsServer(compiler, jsPort, host, longTermCaching, httpsOptions); - const htmlServerPromise = serverRoutes.then(serverRoutesFile => startHtmlServer(serverRoutesFile, port, host, httpsOptions)); + const htmlServerPromise = serverRoutes.then(serverRoutesFile => startHtmlServer(serverRoutesFile, port, host, httpsOptions, customMiddlewarePath)); return { stop: () => Promise.all([jsServer.stop(), htmlServerPromise.then(server => server.stop())]), @@ -59,21 +61,43 @@ export default function start(options){ return startServers(); } + // given the server routes file and a port, start a react-server HTML server at // http://host:port/. returns an object with two properties, started and stop; // see the default function doc for explanation. -const startHtmlServer = (serverRoutes, port, host, httpsOptions) => { +const startHtmlServer = (serverRoutes, port, host, httpsOptions, customMiddlewarePath) => { const server = express(); const httpServer = httpsOptions ? https.createServer(httpsOptions, server) : http.createServer(server); + let middlewareSetup = (server, rsMiddleware) => { + server.use(compression()); + server.use(bodyParser.urlencoded({ extended: false })); + server.use(bodyParser.json()); + rsMiddleware(); + } + return { stop: serverToStopPromise(httpServer), started: new Promise((resolve, reject) => { logger.info("Starting HTML server..."); - server.use(compression()); - server.use(bodyParser.urlencoded({ extended: false })) - server.use(bodyParser.json()) - reactServer.middleware(server, require(serverRoutes)); + let rsMiddlewareCalled = false; + const rsMiddleware = () => { + rsMiddlewareCalled = true; + reactServer.middleware(server, require(serverRoutes)); + } + + if (customMiddlewarePath) { + const customMiddlewareDirAb = path.resolve(process.cwd(), customMiddlewarePath); + middlewareSetup = require(customMiddlewareDirAb).default; + } + + middlewareSetup(server, rsMiddleware); + + if (!rsMiddlewareCalled) { + console.error("Error react-server middleware was never setup in custom middleware function"); + reject("Custom middleware did not setup react-server middleware"); + return; + } httpServer.on('error', (e) => { console.error("Error starting up HTML server"); diff --git a/packages/react-server-cli/src/parseCliArgs.js b/packages/react-server-cli/src/parseCliArgs.js index 4de52de2d..a07d0601b 100644 --- a/packages/react-server-cli/src/parseCliArgs.js +++ b/packages/react-server-cli/src/parseCliArgs.js @@ -62,6 +62,11 @@ export default (args = process.argv) => { default: undefined, type: "boolean", }) + .option("custom-middleware-path", { + describe: "Use custom middleware to be used with react-server", + default: undefined, + type: "string", + }) .option("long-term-caching", { describe: "Use long-term cache headers for the static JS & CSS files. Default is true in production mode, false otherwise.", default: undefined, From 5a808fae68150e9ff657a324720a0ba25362f74a Mon Sep 17 00:00:00 2001 From: Sresan Thevarajah Date: Mon, 10 Oct 2016 23:20:01 -0700 Subject: [PATCH 2/5] change documentation a little --- docs/guides/react-server-cli.md | 2 +- packages/react-server-cli/src/parseCliArgs.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/react-server-cli.md b/docs/guides/react-server-cli.md index d7b3504be..ecddf74ce 100755 --- a/docs/guides/react-server-cli.md +++ b/docs/guides/react-server-cli.md @@ -115,7 +115,7 @@ export default (webpackConfig) => { In the `.reactserverrc` file add an option for `webpack-config` that points to that function file and when React Server is setting up Webpack it will call your function with the result of the built in Webpack options, allowing you to make any modifications needed. ### Use Custom Express Middleware -React Server currently the default Express Middlewares used are compression, body-parser, cookie-parser and of course react-server. If you need to setup custom express middleware you can do it with a setup function. +Currently the default Express Middlewares used are compression, body-parser, cookie-parser. If you need to setup custom express middleware you can do it with a setup function. ```javascript export default (server, reactServerMiddleware) => { diff --git a/packages/react-server-cli/src/parseCliArgs.js b/packages/react-server-cli/src/parseCliArgs.js index a07d0601b..bd331c7ef 100644 --- a/packages/react-server-cli/src/parseCliArgs.js +++ b/packages/react-server-cli/src/parseCliArgs.js @@ -63,7 +63,7 @@ export default (args = process.argv) => { type: "boolean", }) .option("custom-middleware-path", { - describe: "Use custom middleware to be used with react-server", + describe: "Path to custom middleware function file. If it is not defined default setup will be applied", default: undefined, type: "string", }) From 9b6eb54e8fe5b517693749c8a5f3e012d9c384e5 Mon Sep 17 00:00:00 2001 From: Sresan Thevarajah Date: Mon, 10 Oct 2016 23:24:19 -0700 Subject: [PATCH 3/5] More documentation... --- docs/guides/react-server-cli.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/guides/react-server-cli.md b/docs/guides/react-server-cli.md index ecddf74ce..130648eec 100755 --- a/docs/guides/react-server-cli.md +++ b/docs/guides/react-server-cli.md @@ -250,6 +250,11 @@ Minify client JavaScript and CSS. Defaults to **false** in development mode and **true** in production. +#### --custom-middleware-path +Path to the custom middleware function file. If it is not defined the default setup will be applied which include body-parser, compression and cookie-parser. + +Defaults to **undefined**. + #### --long-term-caching Adds hashes to all JavaScript and CSS file names output by the build, allowing for the static files to be served with far-future expires headers. This option From bf4cb789339c130abd7530086b4fcda423ef8fab Mon Sep 17 00:00:00 2001 From: Sresan Thevarajah Date: Mon, 10 Oct 2016 23:27:20 -0700 Subject: [PATCH 4/5] Small edits to describe --- packages/react-server-cli/src/parseCliArgs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-server-cli/src/parseCliArgs.js b/packages/react-server-cli/src/parseCliArgs.js index bd331c7ef..0620b60c7 100644 --- a/packages/react-server-cli/src/parseCliArgs.js +++ b/packages/react-server-cli/src/parseCliArgs.js @@ -63,7 +63,7 @@ export default (args = process.argv) => { type: "boolean", }) .option("custom-middleware-path", { - describe: "Path to custom middleware function file. If it is not defined default setup will be applied", + describe: "Path to custom middleware function file. If it is not defined default setup will be applied.", default: undefined, type: "string", }) From 27b2892e4f5bb995c757755eecca04c0e43d024f Mon Sep 17 00:00:00 2001 From: Sresan Thevarajah Date: Tue, 11 Oct 2016 15:08:04 -0700 Subject: [PATCH 5/5] Fix up documentation after pr feedback --- docs/guides/react-server-cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/react-server-cli.md b/docs/guides/react-server-cli.md index 130648eec..e90c6ccf6 100755 --- a/docs/guides/react-server-cli.md +++ b/docs/guides/react-server-cli.md @@ -123,12 +123,12 @@ export default (server, reactServerMiddleware) => { server.use(bodyParser.urlencoded({ extended: false })); server.use(bodyParser.json()); server.use(session(options)); - rsMiddleware(); // Must be called once or server will not start + reactServerMiddleware(); // Must be called once or server will not start } ``` -In the `.reactserverrc` file add an option for `custom-middleware-path` that points to that function file and when React Server is setting up the server it will call your function for setup rather then the default middlewares mentioned above. On the command line the option is `--custom-middleware-path`. +In the `.reactserverrc` file add an option for `customMiddlewarePath` that points to that function file and when React Server is setting up the server it will call your function for setup rather then the default middlewares mentioned above. This may also be specified on the command line with the `--custom-middleware-path=` option. ### Development mode: making a great DX