Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a32b05f

Browse files
authored
Feature: SSR + Code Splitting 🚀 (#43)
* multi: Prepare for code splitting chore: Add react-loadable to dependencies chore: Move babel options to package.json so they can be retrieved more easily in webpack config chore: Remove webpack patch (https://github.com/gaearon/react-hot-loader/tree/next\#no-patch-required) chore: Update dependencies, move appropriate to devDependencies * feat: split up todos into separate components * chore: move templates to server folder instead * feat: SSR + code splitting 🚀 - Add support for import() syntax in babel and use only on the server (it is already supported on the client with webpack 2) - Update webpack config for import() code splitting - Fix an issue with static fetching for server data * chore: update readme/comments
1 parent cb183a4 commit a32b05f

File tree

36 files changed

+2776
-1104
lines changed

36 files changed

+2776
-1104
lines changed

‎.babelrc‎

Lines changed: 0 additions & 20 deletions
This file was deleted.

‎.env.example‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ APPLICATION_PORT=3000
66
APPLICATION_BASE_URL=http://localhost:3000
77

88
# The output path of server and client files built by webpack and babel.
9-
OUTPUT_PATH=/dist
10-
PUBLIC_OUTPUT_PATH=/dist/public
9+
OUTPUT_PATH=dist
10+
PUBLIC_OUTPUT_PATH=dist/public
1111

1212
# Settings for webpack-dev-server.
1313
DEV_SERVER_PORT=3001
1414
DEV_SERVER_HOSTNAME=localhost
1515
DEV_SERVER_HOST_URL=http://localhost:3001
1616

1717
# The primary asset path. Can be changed to be a CDN URL.
18-
PUBLIC_ASSET_PATH=/assets
18+
PUBLIC_ASSET_PATH=http://localhost:3001/assets/

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ npm-debug.log*
77
# ignore built static files
88
/dist
99
/webpack-assets.json
10+
/webpack-stats.json
11+
/react-loadable.json

‎README.md‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ A universal React/Redux boilerplate with sensible defaults. Out of the box, this
44
boilerplate comes with:
55

66
- Server-side rendering with Express
7+
- Code splitting with Webpack's dynamic `import()`s and [react-loadable](https://github.com/thejameskyle/react-loadable)
78
- Sane [webpack configurations](webpack/)
89
- JS hot reloading with `react-hot-loader` and `webpack-dev-server`
910
- CSS, SASS and `css-modules` support with hot reloading and no [flash of unstyled content](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) (`css-hot-loader`)
1011
- Routing with `react-router-v4`
11-
- Full production builds that do not rely on `babel`.
12+
- Full production builds that do not rely on `babel-node`.
1213

1314
## Get started
1415

@@ -161,13 +162,19 @@ Check the `.eslintignore` file for directories excluded from linting.
161162

162163
## Changing the public asset path
163164

164-
By default, assets are built into `/dist/public`. This path is then served by
165-
express under the path `/assets`. This is the public asset path. In a production
165+
By default, assets are built into `dist/public`. This path is then served by
166+
express under the path `assets`. This is the public asset path. In a production
166167
scenario, you may want your assets to be hosted on a CDN. To do so, just change
167168
the `PUBLIC_ASSET_PATH` environment variant.
168169

169-
If you're using Heroku:
170+
Example using Heroku, if serving via CDN:
170171

171172
```
172173
heroku config:set PUBLIC_ASSET_PATH=https://my.cdn.com
173174
```
175+
176+
Example using Heroku, if serving locally:
177+
178+
```
179+
heroku config:set PUBLIC_ASSET_PATH=/assets
180+
```

‎client/index.js‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
import 'babel-polyfill';
2-
import 'css/base/index.scss';
32
import React from 'react';
43
import ReactDOM from 'react-dom';
54
import { Provider } from 'react-redux';
65
import { ConnectedRouter } from 'react-router-redux';
76
import createHistory from 'history/createBrowserHistory';
87
import configureStore from 'store';
98
import App from 'containers/App';
9+
import Loadable from 'react-loadable';
10+
11+
import './styles';
1012

1113
// Hydrate the redux store from server state.
1214
const initialState = window.__INITIAL_STATE__;
1315
const history = createHistory();
1416
const store = configureStore(initialState, history);
1517

1618
// Render the application
17-
ReactDOM.hydrate(
18-
<Provider store={store}>
19-
<ConnectedRouter history={history}>
20-
<App />
21-
</ConnectedRouter>
22-
</Provider>,
23-
document.getElementById('app')
24-
);
19+
window.main = () => {
20+
Loadable.preloadReady().then(() => {
21+
ReactDOM.hydrate(
22+
<Provider store={store}>
23+
<ConnectedRouter history={history}>
24+
<App />
25+
</ConnectedRouter>
26+
</Provider>,
27+
document.getElementById('app')
28+
);
29+
});
30+
};

‎client/styles.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Include all Vendor CSS here
2+
import 'semantic-ui-css/semantic.min.css';
3+
4+
// Base styles
5+
import 'css/base/index.scss';

‎client/vendor.js‎

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
const Loading = (props) => {
5+
const { error, timedOut, pastDelay } = props;
6+
7+
console.log(props);
8+
9+
if (error) {
10+
// When the loader has errored
11+
return (
12+
<div>Error!</div>
13+
);
14+
} else if (timedOut) {
15+
// When the loader has taken longer than the timeout
16+
return (
17+
<div>Taking a long time...</div>
18+
);
19+
} else if (pastDelay) {
20+
// When the loader has taken longer than the delay
21+
return (
22+
<div>Loading...</div>
23+
);
24+
}
25+
26+
return null;
27+
};
28+
29+
Loading.propTypes = {
30+
error: PropTypes.bool,
31+
timedOut: PropTypes.bool,
32+
pastDelay: PropTypes.bool
33+
};
34+
35+
export default Loading;

‎common/js/components/common/index.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { default as ErrorPage } from './ErrorPage';
22
export { default as Footer } from './Footer';
33
export { default as Header } from './Header';
4+
export { default as Loading } from './Loading';
45
export { default as RouteWithSubRoutes } from './RouteWithSubRoutes';
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import { Form } from 'semantic-ui-react';
4+
import classnames from 'classnames/bind';
5+
import css from './index.scss';
6+
7+
class TodoForm extends Component {
8+
static propTypes = {
9+
onSubmit: PropTypes.func,
10+
className: PropTypes.string
11+
};
12+
13+
state = { todoText: '' };
14+
15+
submitTodo = ev => {
16+
ev.preventDefault();
17+
18+
const { onSubmit } = this.props;
19+
const { todoText } = this.state;
20+
21+
if (todoText && todoText !== '' && typeof onSubmit === 'function') {
22+
onSubmit(todoText);
23+
this.setState({ todoText: '' });
24+
}
25+
};
26+
27+
onTodoChange = ev => {
28+
this.setState({ todoText: ev.target.value });
29+
};
30+
31+
render() {
32+
const { className } = this.props;
33+
const { todoText } = this.state;
34+
35+
return (
36+
<Form
37+
className={classnames(css.todoForm, className)}
38+
onSubmit={this.submitTodo}
39+
>
40+
<Form.Group>
41+
<Form.Input
42+
onChange={this.onTodoChange}
43+
value={todoText}
44+
type="text"
45+
placeholder="Add a todo..."
46+
/>
47+
<Form.Button content="Add" icon="plus" />
48+
</Form.Group>
49+
</Form>
50+
);
51+
}
52+
}
53+
54+
export default TodoForm;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /