-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
534 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": ["react-server"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
build | ||
__clientTemp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
FROM node:slim | ||
|
||
EXPOSE 3000 | ||
ENV NODE_ENV=docker-dev | ||
VOLUME /www |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# react-server-examples/bike-share | ||
|
||
An example project for `react-server` which demos server rendering, interactivity | ||
on the client side, frameback, ReactServerAgent, url parameters and logging. | ||
Uses [api.citybik.es](http://api.citybik.es/v2/) to get data about bike shares | ||
and their availability around the world. | ||
|
||
To start in development mode: | ||
|
||
```shell | ||
npm start | ||
``` | ||
|
||
Then go to [localhost:3000](http://localhost:3000/). You will see an index page | ||
that shows the covered bike share networks around the world. Each bike share | ||
network is a link to a details page that, when clicked, loads an iframe in front | ||
of the index page containing a network page for that bike share network, | ||
including information about each station in that network, and the number of | ||
available bikes the last time that data is available for. | ||
|
||
If you want to optimize the client code at the expense of startup time, type | ||
`NODE_ENV=production npm start`. You can also use | ||
[any react-server-cli arguments](../../react-server-cli#setting-options-manually) | ||
after `--`. For example: | ||
|
||
```shell | ||
# start in dev mode on port 4000 | ||
npm start -- --port=4000 | ||
``` | ||
|
||
# Developing using Docker and Docker Compose | ||
|
||
These steps assume you are familiar with docker and already have it installed. | ||
Some basics: | ||
|
||
1. Download [Docker Toolbox](https://www.docker.com/products/docker-toolbox) and | ||
install it. | ||
2. Start `docker quick start shell` | ||
3. Navigate to where you generated the project | ||
4. Add a configuration to set the `host` option to the ip given by | ||
`docker-machine ip`. An example configuration might be like: | ||
```json | ||
{ | ||
"port": "3000", | ||
"env": { | ||
"docker": { | ||
"host": "Your ip from `docker-machine ip` here" | ||
}, | ||
"staging": { | ||
"port": "3000" | ||
}, | ||
"production": { | ||
"port": "80" | ||
} | ||
} | ||
} | ||
``` | ||
5. Now that your system is ready to go, start the containers: | ||
```shell | ||
docker-compose build --pull | ||
docker-compose up | ||
``` | ||
|
||
The containers will now be running. At any time, press ctrl+c to stop them. | ||
|
||
To clean up, run the following commands: | ||
|
||
```shell | ||
docker-compose stop | ||
docker-compose rm --all | ||
docker volume ls # and get the name of the volume ending in react_server_node_modules | ||
# this name will be different depending on the name of the project | ||
docker volume rm _react_server_node_modules | ||
``` | ||
|
||
The configuration included stores the node_modules directory in a "named volume". | ||
This is a special persistent data-store that Docker uses to keep around the | ||
node_modules directory so that they don't have to be built on each run of the | ||
container. If you need to get into the container in order to investigate what | ||
is in the volume, you can run `docker-compose exec react_server bash` which will | ||
open a shell in the container. Be aware that the exec functionality doesn't | ||
exist in Windows (as of this writing). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import {ReactServerAgent, logging} from 'react-server'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
export default class NetworkApi { | ||
setConfigValues() { | ||
return {isRawResponse: true}; | ||
} | ||
|
||
handleRoute(next) { | ||
this.network = this.getRequest().getQuery().network; | ||
logger.info(`got network api request${this.network ? ' for network ' + this.network : ''}`); | ||
return next(); | ||
} | ||
|
||
getContentType() { | ||
return 'application/json'; | ||
} | ||
|
||
getResponseData() { | ||
let url = 'http://api.citybik.es/v2/networks'; | ||
if (this.network) { | ||
url += `/${this.network}`; | ||
} | ||
return new Promise(resolve => { | ||
ReactServerAgent.get(url).then(data => { | ||
logger.info(`got data ${JSON.stringify(data)} from url ${url}`); | ||
resolve(JSON.stringify(data)); | ||
}); | ||
}); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
packages/react-server-examples/bike-share/components/footer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
import {logging} from 'react-server'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
export default () => { | ||
logger.info('rendering the footer'); | ||
return (<div className="footer"> | ||
<span>Brought to you by </span> | ||
<a href="http://github.com/redfin/react-server">React Server</a> | ||
<span> and </span> | ||
<a href="http://api.citybik.es/v2/">citybik.es</a> | ||
</div>); | ||
}; |
9 changes: 9 additions & 0 deletions
9
packages/react-server-examples/bike-share/components/header.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react'; | ||
import {logging} from 'react-server'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
export default () => { | ||
logger.info('rendering the header'); | ||
return (<h1 className="header">React Server city bikes page</h1>); | ||
}; |
29 changes: 29 additions & 0 deletions
29
packages/react-server-examples/bike-share/components/network-card.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React from 'react'; | ||
import {logging, Link} from 'react-server'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
const NetworkCard = ({id, name, location, company}) => { | ||
logger.info(`rendering card for network ${name}`); | ||
return ( | ||
<div><Link path={`/network?network=${id}`} frameback>{name}</Link> in {location.city}, {location.country}, run by {company}</div> | ||
); | ||
}; | ||
|
||
NetworkCard.propTypes = { | ||
company: React.PropTypes.string, | ||
href: React.PropTypes.string, | ||
id: React.PropTypes.string, | ||
location: React.PropTypes.shape({ | ||
city: React.PropTypes.string, | ||
country: React.PropTypes.string, | ||
latitude: React.PropTypes.number, | ||
longitude: React.PropTypes.number | ||
}), | ||
name: React.PropTypes.string, | ||
stations: React.PropTypes.array | ||
}; | ||
|
||
NetworkCard.displayName = 'NetworkCard'; | ||
|
||
export default NetworkCard; |
21 changes: 21 additions & 0 deletions
21
packages/react-server-examples/bike-share/components/network-list.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import {logging} from 'react-server'; | ||
import NetworkCard from './network-card'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
const NetworkList = ({networks}) => { | ||
logger.info(`rendering list of ${networks.length} networks`); | ||
const networkCards = networks.map(network => { | ||
return <NetworkCard key={network.id} {...network}/>; | ||
}); | ||
return <div>{networkCards}</div>; | ||
}; | ||
|
||
NetworkList.propTypes = { | ||
networks: React.PropTypes.array | ||
}; | ||
|
||
NetworkList.displayName = 'NetworkList'; | ||
|
||
export default NetworkList; |
35 changes: 35 additions & 0 deletions
35
packages/react-server-examples/bike-share/components/station-card.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react'; | ||
import {logging} from 'react-server'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
const timeSinceTimestamp = s => { | ||
const parsed = Date.parse(s); | ||
const timeSince = (new Date()) - parsed; | ||
const minutesSince = Math.floor(timeSince / 60000); | ||
const secondsSince = Math.floor((timeSince / 1000) % 60); | ||
return `${minutesSince} min, ${secondsSince} sec`; | ||
}; | ||
|
||
const StationCard = ({station}) => { | ||
logger.info(`rendering card for station ${JSON.stringify(station)}`); | ||
return ( | ||
<div>{station.name} had {station.empty_slots} empty slots {timeSinceTimestamp(station.timestamp)} ago.</div> | ||
); | ||
}; | ||
|
||
StationCard.propTypes = { | ||
station: React.PropTypes.shape({ | ||
empty_slots: React.PropTypes.number, // eslint-disable-line | ||
extra: React.PropTypes.object, | ||
free_bikes: React.PropTypes.number, // eslint-disable-line | ||
id: React.PropTypes.string, | ||
latitude: React.PropTypes.number, | ||
longitude: React.PropTypes.number, | ||
name: React.PropTypes.string, | ||
timestamp: React.PropTypes.string | ||
}) | ||
}; | ||
|
||
StationCard.displayName = 'StationCard'; | ||
|
||
export default StationCard; |
19 changes: 19 additions & 0 deletions
19
packages/react-server-examples/bike-share/components/station-list.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react'; | ||
import {logging} from 'react-server'; | ||
import StationCard from './station-card'; | ||
|
||
const logger = logging.getLogger(__LOGGER__); | ||
|
||
const StationList = ({stations}) => { | ||
logger.info(`rendering list of ${stations.length} stations`); | ||
const stationCards = stations.map(station => <StationCard station={station} key={station.id}/>); | ||
return <div>{stationCards}</div>; | ||
}; | ||
|
||
StationList.propTypes = { | ||
stations: React.PropTypes.array | ||
}; | ||
|
||
StationList.displayName = 'StationList'; | ||
|
||
export default StationList; |
22 changes: 22 additions & 0 deletions
22
packages/react-server-examples/bike-share/docker-compose.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
version: '2' | ||
services: | ||
react_server: # The label of the service | ||
build: . # The location of the Dockerfile to build | ||
volumes: # Files to share with the container and the host | ||
- .:/www # Share the project in /www in the container | ||
- react_server_node_modules:/www/node_modules # A special volume so that OS specific node_modules are built correctly | ||
working_dir: /www # The location all commands should run from | ||
environment: | ||
NODE_ENV: 'docker' # Set the NODE_ENV environment variable | ||
command: /bin/bash -c "npm install && npm start" # The command to run in when the container starts | ||
ports: # Ports to expose to your host | ||
- '3000:3000' | ||
- '3001:3001' | ||
# An example database | ||
# my_db: | ||
# image: rethinkdb:latest | ||
# You can reference the db/service by using the dns name `my_db` and docker will do the rest | ||
|
||
# Volume to store separate from the container runtime and host | ||
volumes: | ||
react_server_node_modules: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const gulp = require('gulp'); | ||
const tagger = require('react-server-gulp-module-tagger'); | ||
const babel = require('gulp-babel'); | ||
|
||
gulp.task('default', () => { | ||
gulp.src(['api/*.js', 'components/*.js', 'middleware/*.js', 'pages/*.js', 'routes.js'], {base: '.'}) | ||
.pipe(tagger()) | ||
.pipe(babel({ | ||
presets: ['react-server'] | ||
})) | ||
.pipe(gulp.dest('build/')); | ||
}); |
11 changes: 11 additions & 0 deletions
11
packages/react-server-examples/bike-share/middleware/request-to-port.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import {ReactServerAgent} from 'react-server'; | ||
export default class RequestToPortMiddleware { | ||
handleRoute(next) { | ||
if (typeof window === 'undefined') { //eslint-disable-line | ||
ReactServerAgent.plugRequest(req => { | ||
req.urlPrefix('localhost:3000'); | ||
}); | ||
} | ||
return next(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "react-server-bike-share", | ||
"version": "0.0.1", | ||
"private": true, | ||
"description": "A react-server instance", | ||
"main": "HelloWorld.js", | ||
"author": "Doug Wade <[email protected]>", | ||
"scripts": { | ||
"clean": "rm -rf build __clientTemp", | ||
"start": "npm run clean && gulp && npm run styles && react-server-cli --routesFile build/routes.js", | ||
"styles": "node-sass styles/index.scss build/styles/index.css && node-sass styles/network.scss build/styles/network.css", | ||
"test": "xo && nsp check" | ||
}, | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"babel-plugin-transform-runtime": "^6.8.0", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-runtime": "^6.6.1", | ||
"react": "~0.14.2", | ||
"react-dom": "~0.14.2", | ||
"react-server": "^0.3.1", | ||
"react-server-cli": "^0.3.1", | ||
"superagent": "1.2.0" | ||
}, | ||
"devDependencies": { | ||
"babel-preset-react-server": "^0.3.0", | ||
"eslint-config-xo-react": "^0.7.0", | ||
"eslint-plugin-react": "^5.1.1", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2", | ||
"node-sass": "^3.7.0", | ||
"nsp": "^2.3.3", | ||
"react-server-gulp-module-tagger": "^0.3.0", | ||
"xo": "^0.15.1" | ||
}, | ||
"xo": { | ||
"esnext": true, | ||
"extends": "xo-react", | ||
"globals": [ | ||
"__LOGGER__" | ||
], | ||
"ignores": [ | ||
"__clientTemp/**/*" | ||
] | ||
} | ||
} |
Oops, something went wrong.