Skip to content

Commit

Permalink
Add Express server at port 3001 to render components
Browse files Browse the repository at this point in the history
The express server will take the requested path and serialized state
as input and will return the HTML representation as well as the state
embedded in script tags. You will want to use something like supervisor
to restart the server on component changes. Technically we could have
used Webpack to hotload the changes, but I couldn't figure it out
  • Loading branch information
nambrot committed Apr 1, 2015
1 parent 37556d9 commit 545326e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
1 change: 1 addition & 0 deletions DevProcfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
web: rails s
webpack: webpack-dev-server --config app/assets/webpack.config.js --progress --inline --module-bind --hot
node: supervisor -e node,js,coffee,jsx,cjsx app/assets/javascripts/component_render_server.js
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ We are going to set the barebones of the Flux architecture without thinking too

The first step to server side rendering is to be able to deserialize data into the store for the client. This also avoids the inital request for data. React is also smart enough to not touch the DOM as the resulting HTML is identical.

### 4. Add Server-Side Rendering

We are going to use a simple express server which will take the 1. route and 2. serializedState as parameters and simply return the HTML.

### Not Adressing

1. User Authentication
Expand Down
28 changes: 28 additions & 0 deletions app/assets/javascripts/component_render_server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var renderToString = require('enhanced-require')(module, {
resolve: {
extensions: ['', '.js', '.jsx', '.cjsx', '.coffee'],
modulesDirectories: ["node_modules", "javascripts"]
},

module: {
loaders: [
{ test: /\.js?$/, loaders: []},
{ test: /\.jsx?$/, loaders: ['jsx-loader'] },
{ test: /\.cjsx$/, loaders: ["react-hot", "coffee", "cjsx"]},
{ test: /\.coffee$/, loader: "coffee"},
{ test: /\.json$/, loader: "json-loader"}
]
}
})('render_to_string')

var express = require('express')
var app = express()

app.use(require("body-parser").json());
app.post('/', function (req, res) {
renderToString(req.body.path, req.body.serializedStoreState, function(s){
res.end(s)
});
})

var server = app.listen(3001)
19 changes: 19 additions & 0 deletions app/assets/javascripts/render_to_string.cjsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
React = require('react')
Router = require('react-router')
routes = require('./routes')

Flux = require('flux')
FluxComponent = require('flummox/component')

renderToString = (route, serializedStoreState, callback) ->
flux = new Flux()
flux.deserialize(serializedStoreState)

Router.run routes, route, (Handler, state) ->
html = React.renderToString(<FluxComponent flux={flux} render={ => <Handler />}></FluxComponent>)
embeddedStoreState = "<script>"
embeddedStoreState += "window.serializedStoreState = " + JSON.stringify(serializedStoreState)
embeddedStoreState += "</script>"
callback (html + embeddedStoreState)

module.exports = renderToString
5 changes: 4 additions & 1 deletion app/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"react-router": "*",
"immutable": "*",
"flummox": "*",
"axios": "*"
"axios": "*",
"express": "^4.12.0",
"enhanced-require": "*",
"body-parser": "*"
}
}

0 comments on commit 545326e

Please sign in to comment.