Skip to content

Commit d137589

Browse files
committed
init
0 parents  commit d137589

File tree

14 files changed

+320
-0
lines changed

14 files changed

+320
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cra-server-ex.graffle

Procfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
web: ./node_modules/.bin/react-scripts start
2+
api: PORT=3001 ./node_modules/.bin/babel-node server.js

README.cq.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# `create-react-app` with a server example
2+
3+
[![Dolpins](https://cdn.rawgit.com/fullstackio/cq/master/doc/readme/dolphins-badge-ff00ff.svg)](https://www.fullstackreact.com)
4+
5+
This project demonstrates using the setup generated by `create-react-app` alongside a Node Express API server. You can use it as a starting point for your own projects.
6+
7+
## Running
8+
9+
```
10+
git clone git@github.com:fullstackreact/create-react-app-with-server.git
11+
cd create-react-app-with-server
12+
npm i
13+
npm start
14+
```
15+
16+
## Overview
17+
18+
`create-react-app` configures a Webpack development server to run on `localhost:3000`. This development server will bundle all static assets located under `src/`. All requests to `localhost:3000` will serve `index.html` which will include Webpack's `bundle.js`.
19+
20+
In this example, the React component `App` makes a request to an API server (`server.js`). The user interacts exclusively with the Webpack dev server at `localhost:3000`. The Webpack dev server communicates with the API server when needed at `localhost:3001`:
21+
22+
![Flow diagram](./flow-diagram.png)
23+
24+
This setup uses [node-foreman](https://github.com/strongloop/node-foreman) for process management. Executing `npm start` instructs Foreman to boot both the Webpack dev server and the API server.
25+
26+
## DIY
27+
28+
You can get here yourself using `create-react-app` as a starting point.
29+
30+
The additions to the `create-react-app` boilerplate are listed below.
31+
32+
### `package.json`
33+
34+
Includes extra dependencies for our API server.
35+
36+
`npm start` executes `nf start` (Foreman's start command).
37+
38+
### `Procfile`
39+
40+
Foreman commands for booting the Webpack dev server (`web`) and the API server (`api`):
41+
42+
```
43+
web: ./node_modules/.bin/react-scripts start
44+
api: PORT=3001 ./node_modules/.bin/babel-node server.js
45+
```
46+
47+
(More info on `node-foreman` and Procfiles [here](https://github.com/strongloop/node-foreman)).
48+
49+
### `App.js`
50+
51+
Inside of the `App` component, we make a sample request to the API server using Fetch:
52+
53+
{lang=javascript,crop-query=choose(.fetch,1),format=gfm}
54+
<<[](src/App.js)
55+
56+
### `server.js`
57+
58+
The API server. The important bit of configuration is **white-listing an origin domain**.
59+
60+
The user is communicating with `localhost:3000`. Yet, as demonstrated above, Fetch makes a request to `localhost:3001` — a different domain. Browsers restrict HTTP requests within scripts to the same domain.
61+
62+
In our API server, we let the browser know it's OK if a request is originating from `localhost:3000`:
63+
64+
{lang=javascript,crop-query=context(.allowCrossDomain,0,1),format=gfm}
65+
<<[](server.js)

README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# `create-react-app` with a server example
2+
3+
[![Dolpins](https://cdn.rawgit.com/fullstackio/cq/master/doc/readme/dolphins-badge-ff00ff.svg)](https://www.fullstackreact.com)
4+
5+
This project demonstrates using the setup generated by `create-react-app` alongside a Node Express API server. You can use it as a starting point for your own projects.
6+
7+
## Running
8+
9+
```
10+
git clone git@github.com:fullstackreact/create-react-app-with-server.git
11+
cd create-react-app-with-server
12+
npm i
13+
npm start
14+
```
15+
16+
## Overview
17+
18+
`create-react-app` configures a Webpack development server to run on `localhost:3000`. This development server will bundle all static assets located under `src/`. All requests to `localhost:3000` will serve `index.html` which will include Webpack's `bundle.js`.
19+
20+
In this example, the React component `App` makes a request to an API server (`server.js`). The user interacts exclusively with the Webpack dev server at `localhost:3000`. The Webpack dev server communicates with the API server when needed at `localhost:3001`:
21+
22+
![Flow diagram](./flow-diagram.png)
23+
24+
This setup uses [node-foreman](https://github.com/strongloop/node-foreman) for process management. Executing `npm start` instructs Foreman to boot both the Webpack dev server and the API server.
25+
26+
## DIY
27+
28+
You can get here yourself using `create-react-app` as a starting point.
29+
30+
The additions to the `create-react-app` boilerplate are listed below.
31+
32+
### `package.json`
33+
34+
Includes extra dependencies for our API server.
35+
36+
`npm start` executes `nf start` (Foreman's start command).
37+
38+
### `Procfile`
39+
40+
Foreman commands for booting the Webpack dev server (`web`) and the API server (`api`):
41+
42+
```
43+
web: ./node_modules/.bin/react-scripts start
44+
api: PORT=3001 ./node_modules/.bin/babel-node server.js
45+
```
46+
47+
(More info on `node-foreman` and Procfiles [here](https://github.com/strongloop/node-foreman)).
48+
49+
### `App.js`
50+
51+
Inside of the `App` component, we make a sample request to the API server using Fetch:
52+
53+
```javascript
54+
fetch('http://localhost:3001/api/forecast', {
55+
accept: 'application/json',
56+
}).then(parseJSON)
57+
```
58+
59+
### `server.js`
60+
61+
The API server. The important bit of configuration is **white-listing an origin domain**.
62+
63+
The user is communicating with `localhost:3000`. Yet, as demonstrated above, Fetch makes a request to `localhost:3001` — a different domain. Browsers restrict HTTP requests within scripts to the same domain.
64+
65+
In our API server, we let the browser know it's OK if a request is originating from `localhost:3000`:
66+
67+
```javascript
68+
const allowCrossDomain = function (req, res, next) {
69+
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
70+
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
71+
res.header('Access-Control-Allow-Headers', 'Content-Type');
72+
73+
next();
74+
};
75+
app.use(allowCrossDomain);
76+
```

favicon.ico

24.3 KB
Binary file not shown.

flow-diagram.png

66.9 KB
Loading

index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>React App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
</body>
11+
</html>

package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "calo",
3+
"version": "0.0.1",
4+
"private": true,
5+
"devDependencies": {
6+
"react-scripts": "0.1.0"
7+
},
8+
"babel": {
9+
"presets": [ "es2015", "stage-0" ]
10+
},
11+
"dependencies": {
12+
"babel-cli": "6.6.5",
13+
"babel-core": "6.4.5",
14+
"babel-preset-es2015": "6.3.13",
15+
"babel-preset-stage-0": "6.5.0",
16+
"express": "4.13.3",
17+
"foreman": "1.4.1",
18+
"isomorphic-fetch": "^2.2.1",
19+
"react": "15.2.1",
20+
"react-dom": "15.2.1"
21+
},
22+
"scripts": {
23+
"start": "nf start",
24+
"generate-readme": "cqmd -o README.md -p . README.cq.md"
25+
}
26+
}

server.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const express = require('express');
2+
3+
const app = express();
4+
5+
app.set('port', (process.env.PORT || 3001));
6+
7+
// Allow requests from pages served by Webpack
8+
const allowCrossDomain = function (req, res, next) {
9+
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
10+
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
11+
res.header('Access-Control-Allow-Headers', 'Content-Type');
12+
13+
next();
14+
};
15+
app.use(allowCrossDomain);
16+
17+
app.get('/api/forecast', (req, res) => {
18+
res.json({
19+
text: 'Server says: Another scorcher!',
20+
});
21+
});
22+
23+
app.listen(app.get('port'), () => {
24+
console.log(`Find the server at: http://localhost:${app.get('port')}/`); // eslint-disable-line no-console
25+
});

src/App.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.App {
2+
text-align: center;
3+
}
4+
5+
.App-logo {
6+
animation: spin infinite 20s linear;
7+
height: 80px;
8+
}
9+
10+
.App-header {
11+
background-color: #222;
12+
height: 150px;
13+
padding: 20px;
14+
color: white;
15+
}
16+
17+
.App-intro {
18+
font-size: large;
19+
}
20+
21+
@keyframes spin {
22+
from { transform: rotate(0deg); }
23+
to { transform: rotate(360deg); }
24+
}

0 commit comments

Comments
 (0)