Skip to content

Commit 44f19f6

Browse files
committed
frontend example with webpack
1 parent 10f31e3 commit 44f19f6

File tree

14 files changed

+7138
-0
lines changed

14 files changed

+7138
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Running the example
2+
===================
3+
4+
Install the dependencies
5+
6+
```
7+
pip install -r requirements.txt
8+
npm install
9+
```
10+
11+
Start the render server
12+
13+
```
14+
node render_server.js
15+
```
16+
17+
Start the python server
18+
19+
```
20+
python example.py
21+
```
22+
23+
And visit [http://127.0.0.1:5000](http://127.0.0.1:5000)
24+
25+
### Notes
26+
To make React attributes like `onClick` etc. work, the app has to be re-rendered when it loads on the browswer. React is intelligent enough to not re-paint the browser and only update the changes, thus adding all the component properties.
27+
28+
29+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import os
2+
from flask import Flask, render_template, request, redirect, jsonify
3+
from react.render import render_component
4+
5+
DEBUG = True
6+
7+
app = Flask(__name__)
8+
app.debug = DEBUG
9+
10+
comments = []
11+
components_path = os.path.join(os.path.dirname(__file__), 'src')
12+
13+
def path(js_file):
14+
return os.path.join(components_path, js_file)
15+
16+
@app.route('/')
17+
def index():
18+
store = {'component': 'CommentBox.jsx'}
19+
store['props'] = {'comments': comments}
20+
21+
rendered = render_component(
22+
os.path.join(os.getcwd(), 'static', 'js', path(store['component'])),
23+
{
24+
'comments': comments,
25+
'url': '/comment/',
26+
},
27+
to_static_markup=True,
28+
)
29+
30+
return render_template('index.html',
31+
rendered=rendered,
32+
store=store)
33+
34+
35+
@app.route('/comment/', methods=('POST',))
36+
def comment():
37+
comments.append({
38+
'author': request.form['author'],
39+
'text': request.form['text'],
40+
})
41+
return jsonify({'comments': comments})
42+
43+
@app.route('/clear/')
44+
def clear():
45+
comments = []
46+
return jsonify({'comments': comments})
47+
48+
if __name__ == '__main__':
49+
app.run()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"watch": "webpack --watch & forever --watch --watchDirectory ./static/js/src ./render_server.js"
5+
},
6+
"dependencies": {
7+
"babel-core": "^6.1.20",
8+
"babel-loader": "^6.2.4",
9+
"babel-plugin-transform-react-jsx": "^6.1.18",
10+
"babel-preset-es2015": "^6.9.0",
11+
"babel-preset-react": "^6.5.0",
12+
"body-parser": "^1.14.1",
13+
"express": "^4.13.3",
14+
"forever": "^0.15.2",
15+
"react": "^0.14.2",
16+
"react-dom": "^0.14.2",
17+
"react-render": "^1.1.0",
18+
"require": "^2.4.20",
19+
"webpack": "^1.13.1",
20+
"yargs": "^3.29.0"
21+
},
22+
"babel": {
23+
"presets": [
24+
"es2015",
25+
"react"
26+
]
27+
}
28+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
var argv = require('yargs')
2+
.option('p', {
3+
alias: 'port',
4+
description: 'Specify the server\'s port',
5+
default: 9009
6+
})
7+
.option('a', {
8+
alias: 'address',
9+
description: 'Specify the server\'s address',
10+
default: '127.0.0.1'
11+
})
12+
.help('h').alias('h', 'help')
13+
.strict()
14+
.argv;
15+
16+
var http = require('http');
17+
var express = require('express');
18+
var bodyParser = require('body-parser');
19+
var reactRender = require('react-render');
20+
21+
// Ensure support for loading files that contain ES6+7 & JSX
22+
require('babel-core/register');
23+
24+
var ADDRESS = argv.address;
25+
var PORT = argv.port;
26+
27+
var app = express();
28+
var server = http.Server(app);
29+
30+
app.use(bodyParser.json());
31+
32+
app.get('/', function(req, res) {
33+
res.end('React render server');
34+
});
35+
36+
app.post('/render', function(req, res) {
37+
reactRender(req.body, function(err, markup) {
38+
if (err) {
39+
res.json({
40+
error: {
41+
type: err.constructor.name,
42+
message: err.message,
43+
stack: err.stack
44+
},
45+
markup: null
46+
});
47+
} else {
48+
res.json({
49+
error: null,
50+
markup: markup
51+
});
52+
}
53+
});
54+
});
55+
56+
server.listen(PORT, ADDRESS, function() {
57+
console.log('React render server listening at http://' + ADDRESS + ':' + PORT);
58+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
flask==0.10.1
2+
optional-django==0.3.0
3+
requests==2.7.0
4+
react
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
h2 {
2+
border-bottom: 1px solid #eee;
3+
}
4+
5+
form label {
6+
display: block;
7+
}
8+
9+
form button {
10+
margin-left: 5px;
11+
}
12+
13+
.btn-danger {
14+
float: right;
15+
}

0 commit comments

Comments
 (0)