Skip to content

Commit f88293b

Browse files
committed
Refactored slightly so that the components file only exports the components and the server and browser specific render methods are in their own files
1 parent 39c6738 commit f88293b

File tree

10 files changed

+64
-56
lines changed

10 files changed

+64
-56
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Naturally this means all of the other server language implementations have been
88

99
## Implementation
1010

11-
The example file from the tutorial is now in a publicly-inaccessible location at `src/example.js`. The templates are in another file which is `require`d from there, `templates.jsx`.
11+
The example file from the tutorial is now in a publicly-inaccessible location at `components/components.js`. This exports each component in `module.exports`. The templates are in another file which is `require`d from there, `templates.jsx`.
1212

13-
In the browser, the main entry point method which calls `ReactDOM.render`, is exported as `render` from `example.js`. This is made accessible as a window method in `src/index.js`, which is used as the entry script for `webpack`. This is all compiled into `public/scripts/bundle.js` which is what the browser includes. The settings for the `webpack` are found in `webpack.config.js`; several libraries like React itself and the markdown parser are set to be externals, which means they are not bundled up so that the browser can load those from a CDN (Content Delivery Network).
13+
In the browser, the main entry point method which calls `ReactDOM.render`, is added as a global window method, `renderCommentBox` in `components/browser.js`, which is used as the entry script for `webpack`. This is all compiled into `public/scripts/bundle.js` which is what the browser includes. The settings for the `webpack` are found in `webpack.config.js`; several libraries like React itself and the markdown parser are set to be externals, which means they are not bundled up so that the browser can load those from a CDN (Content Delivery Network).
1414

15-
On the browser, `example.js` itself is `require`d, after the `node-jsx` module is set up, in order that the JSX syntax can be understood. `example.js` also exports a `renderServer` which returns a static string after calling `ReactDOMServer.renderToString` from the `react-dom/server` module. The route for `/` simply calls this method and passes it as a variable to the `views/index.html` view.
15+
On the browser, `components/server.js` is `require`d, after the `node-jsx` module is set up, in order that the JSX syntax can be understood. This exports a `renderCommentBox` method which returns a static string after calling `ReactDOMServer.renderToString` from the `react-dom/server` module. The route for `/` simply calls this method and passes it as a variable to the `views/index.html` view.
1616

1717
## To use
1818

components/browser.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
var components = require('./components');
2+
var ReactDOM = require('react-dom');
3+
4+
/**
5+
* Load the comments via AJAX before rendering the comment box with the DOM.
6+
* This will avoid the server rendered comments being replaced with nothing by JS.
7+
* If the AJAX call fails, then just render no comments after logging the error.
8+
*/
9+
window.renderCommentBox = () => {
10+
var url = "/api/comments";
11+
12+
$.get(url).then(
13+
(comments) => {
14+
return comments;
15+
},
16+
(err) => {
17+
console.error(url, err);
18+
return [];
19+
}
20+
)
21+
.always((comments) => {
22+
ReactDOM.render(React.createElement(components.CommentBox, {
23+
url: url,
24+
pollInterval: 2000,
25+
comments: comments
26+
}), document.getElementById('content'));
27+
});
28+
};

src/example.js renamed to components/components.js

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
var templates = require('./templates.jsx');
1414
var React = require('react');
1515
var marked = require('marked');
16-
17-
var ReactDOMServer = typeof window === "undefined" ? require('react-dom/server') : undefined;
16+
var $ = require('jquery');
1817

1918
var Comment = React.createClass({
2019
displayName: 'Comment',
@@ -34,7 +33,7 @@ var CommentBox = React.createClass({
3433
this.setState({data: data});
3534
},
3635
(err) => {
37-
console.error(this.props.url, err.status, err.statusText);
36+
console.error(this.props.url, err);
3837
}
3938
);
4039
},
@@ -104,44 +103,9 @@ var CommentForm = React.createClass({
104103
render: templates.commentForm
105104
});
106105

107-
108106
module.exports = {
109-
/**
110-
* Load the comments via AJAX before rendering the comment box with the DOM.
111-
* This will avoid the server rendered comments being replaced with nothing by JS.
112-
* If the AJAX call fails, then just render no comments after logging the error.
113-
*/
114-
render: () => {
115-
var url = "/api/comments";
116-
117-
$.get(url).then(
118-
(comments) => {
119-
return comments;
120-
},
121-
(err) => {
122-
console.error(this.props.url, err.status, err.statusText);
123-
return [];
124-
}
125-
)
126-
.always((comments) => {
127-
ReactDOM.render(React.createElement(CommentBox, {
128-
url: url,
129-
pollInterval: 2000,
130-
comments: comments
131-
}), document.getElementById('content'));
132-
});
133-
},
134-
/**
135-
* Just return a static string to render on the server
136-
*
137-
* @param {Array} comments
138-
* @returns {String}
139-
*/
140-
renderServer: (comments) => {
141-
return ReactDOMServer.renderToString(React.createElement(CommentBox, {
142-
url: "/api/comments",
143-
pollInterval: 2000,
144-
comments: comments
145-
}));
146-
}
107+
Comment,
108+
CommentBox,
109+
CommentList,
110+
CommentForm
147111
};

components/server.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var components = require('./components');
2+
var React = require('react');
3+
var ReactDOMServer = require('react-dom/server');
4+
5+
module.exports = {
6+
/**
7+
* Just return a static string to render on the server
8+
*
9+
* @param {Object} params
10+
* @returns {String}
11+
*/
12+
renderCommentBox: (params) => {
13+
return ReactDOMServer.renderToString(React.createElement(components.CommentBox, params));
14+
}
15+
};
File renamed without changes.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"dependencies": {
77
"body-parser": "^1.4.3",
88
"express": "^4.4.5",
9+
"jquery": "^2.2.0",
910
"marked": "^0.3.5",
1011
"node-jsx": "^0.13.3",
1112
"react": "^0.14.7",

server.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var bodyParser = require('body-parser');
1717
var swig = require('swig');
1818

1919
require('node-jsx').install();
20-
var example = require('./src/example');
20+
var components = require('./components/server');
2121

2222
var app = express();
2323

@@ -43,7 +43,9 @@ app.get('/', function(req, res) {
4343
}
4444

4545
res.render('index', {
46-
commentBox: example.renderServer(JSON.parse(data))
46+
commentBox: components.renderCommentBox({
47+
comments: JSON.parse(data)
48+
})
4749
});
4850
});
4951
});

src/index.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

views/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
{{ commentBox }}
1818
{% endautoescape %}
1919
</div>
20-
<script type="text/javascript">commentBoxRender();</script>
20+
<script type="text/javascript">renderCommentBox();</script>
2121
</body>
2222
</html>

webpack.config.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
var webpack = require("webpack");
22
var isDev = process.argv.indexOf('--dev') > -1;
33

4-
// Don't include react-dom/server in the browser
5-
var ignore = new webpack.IgnorePlugin(/react-dom/);
6-
74
module.exports = {
8-
entry: "./src/index.js",
5+
entry: "./components/browser.js",
96
output: {
107
path: "./public/scripts",
118
filename: "bundle.js"
129
},
1310
// These libraries are included in separate script tags and are available as global variables
1411
externals: {
1512
"react": "React",
16-
"marked": "marked"
13+
"marked": "marked",
14+
"jquery": "jQuery",
15+
"react-dom": "ReactDOM"
1716
},
1817
plugins: isDev ?
19-
[ignore] :
20-
[ignore, new webpack.optimize.UglifyJsPlugin({minimize: true})],
18+
[] :
19+
[new webpack.optimize.UglifyJsPlugin({minimize: true})],
2120
devtool: isDev ? 'source-map' : null,
2221
module: {
2322
loaders: [

0 commit comments

Comments
 (0)