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
0 parents
commit c325d62
Showing
23 changed files
with
724 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,8 @@ | ||
node_modules/ | ||
*.DS_Store | ||
static/ | ||
build/ | ||
.tmp/ | ||
nginx.conf | ||
npm-debug.log | ||
webpack-assets.json |
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,61 @@ | ||
# React Static Plate | ||
|
||
> Build static sites with React to host on [Amazon S3](https://aws.amazon.com/s3/), [Github Pages](https://pages.github.com/), [Surge](https://surge.sh/) et cetera<br> | ||
> (React.js, React Router, Radium, Babel 6, Webpack) | ||
### Features | ||
|
||
✓ ES6+.<br> | ||
✓ Hot Reloading.<br> | ||
✓ ESLint rules based on Airbnb's Javascript Styleguide.<br> | ||
✓ Every route is completely rendered into a `.html` page with `renderToString`.<br> | ||
✓ Deferred script loading, so the browser can render the html without waiting for the js bundle first.<br> | ||
✓ Hash is added to every asset's filename, so you can cache all assets forever.<br> | ||
✓ Title, Meta and other SEO tags with [react-helmet](https://github.com/nfl/react-helmet).<br> | ||
✓ SEO friendly, no JavaScript required to view a page.<br> | ||
✓ Generates sitemap.xml <br> | ||
|
||
### Getting Started | ||
|
||
Clone the repo, install Node modules and run the development server: | ||
|
||
``` | ||
$ git clone -o react-static-plate -b master --single-branch \ | ||
https://github.com/webyak/react-static-plate.git my-site | ||
$ cd my-site | ||
$ npm install | ||
$ npm start | ||
``` | ||
|
||
Then open [http://localhost:3000](http://localhost:3000) and have fun ;) | ||
|
||
### Deploy | ||
|
||
Set your `host` in `config.json` and generate all the static files with `npm run build`. Then upload the contents of the `build/` folder to your hosting solution of choice. Finish. | ||
|
||
You can also see the production site on your local machine using `http-server`: | ||
|
||
``` | ||
$ npm install -g http-server | ||
$ cd build | ||
$ http-server | ||
``` | ||
|
||
### Update | ||
|
||
You can fetch and merge recent changes from this repo into your own project: | ||
|
||
``` | ||
$ git checkout master | ||
$ git fetch react-static-plate | ||
$ git merge react-static-plate/master | ||
$ npm install | ||
``` | ||
|
||
### FAQ | ||
|
||
**My site is not working properly on Amazon S3**:<br> | ||
Make sure you define paths *with* trailing slashes, like `<Route path="about/">`. | ||
|
||
**My site is not working properly on Github Pages**:<br> | ||
Make sure you define paths *without* trailing slashes, like `<Route path="about">`. |
Binary file not shown.
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,33 @@ | ||
// ================================================== | ||
// Hello | ||
// ================================================== | ||
|
||
import React from 'react'; | ||
import Radium from 'radium'; | ||
|
||
import colors from '../styling/colors.js'; | ||
import commonStyles from '../styling/common_styles.js'; | ||
|
||
const { resetHeading } = commonStyles; | ||
const { darkGray } = colors; | ||
|
||
const style = { | ||
padding: '8rem 0', | ||
textAlign: 'center', | ||
}; | ||
const headingStyle = { | ||
...resetHeading, | ||
color: darkGray, | ||
cursor: 'default', | ||
':hover': { | ||
fontWeight: 'bold', | ||
}, | ||
}; | ||
|
||
const Hello = () => ( | ||
<div style={style}> | ||
<h1 style={headingStyle}>Hi, React.</h1> | ||
</div> | ||
); | ||
|
||
export default Radium(Hello); |
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 @@ | ||
// ================================================== | ||
// Layout | ||
// ================================================== | ||
|
||
import React from 'react'; | ||
import Radium, { StyleRoot, Style } from 'radium'; | ||
import Helmet from 'react-helmet'; | ||
|
||
const Layout = ({ children }) => ( | ||
<StyleRoot> | ||
<Helmet | ||
title="My site" | ||
meta={[{ name: 'description', content: 'A static site.' }]} | ||
link={[{ rel: 'shortcut icon', href: require('../assets/favicon.ico') }]} | ||
/> | ||
<Style | ||
rules={{ | ||
'html, body': { | ||
width: '100%', | ||
height: '100%', | ||
}, | ||
'*, *:before, *:after': { | ||
boxSizing: 'border-box', | ||
}, | ||
}} | ||
/> | ||
{children} | ||
</StyleRoot> | ||
); | ||
|
||
Layout.propTypes = { | ||
children: React.PropTypes.element, | ||
}; | ||
|
||
export default Radium(Layout); |
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 @@ | ||
// ================================================== | ||
// NotFound | ||
// ================================================== | ||
|
||
import React from 'react'; | ||
import Radium from 'radium'; | ||
|
||
const NotFound = () => ( | ||
<div>404</div> | ||
); | ||
|
||
export default Radium(NotFound); |
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,16 @@ | ||
// ================================================== | ||
// Root | ||
// ---- | ||
// Entry component for hot reloading. | ||
// ================================================== | ||
|
||
import React from 'react'; | ||
import { Router, browserHistory } from 'react-router'; | ||
|
||
import routes from '../routes.js'; | ||
|
||
const Root = () => ( | ||
<Router routes={routes} history={browserHistory} /> | ||
); | ||
|
||
export default Root; |
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,41 @@ | ||
/* eslint-disable global-require */ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
|
||
const rootEl = document.getElementById('react-root'); | ||
|
||
let render = () => { | ||
const Root = require('./components/root.js').default; | ||
|
||
ReactDOM.render( | ||
<Root />, | ||
rootEl | ||
); | ||
}; | ||
|
||
// manually rerender on hot reloads and show errors in development. | ||
if (module.hot) { | ||
const renderApp = render; | ||
|
||
const renderError = (error) => { | ||
const RedBox = require('redbox-react'); | ||
ReactDOM.render( | ||
<RedBox error={error} />, | ||
rootEl | ||
); | ||
}; | ||
|
||
render = () => { | ||
try { | ||
renderApp(); | ||
} catch (error) { | ||
renderError(error); | ||
} | ||
}; | ||
|
||
module.hot.accept('./components/root.js', () => { | ||
render(); | ||
}); | ||
} | ||
|
||
render(); |
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,15 @@ | ||
import React from 'react'; | ||
import { Route, IndexRoute } from 'react-router'; | ||
|
||
import Layout from './components/layout.js'; | ||
import Hello from './components/hello.js'; | ||
import NotFound from './components/not_found.js'; | ||
|
||
const routes = ( | ||
<Route path="/" component={Layout}> | ||
<IndexRoute component={Hello} /> | ||
<Route path="*" component={NotFound} /> | ||
</Route> | ||
); | ||
|
||
export default routes; |
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 @@ | ||
const colors = { | ||
darkGray: '#323233', | ||
}; | ||
|
||
export default colors; |
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,10 @@ | ||
const commonStyles = { | ||
resetHeading: { | ||
padding: 0, | ||
margin: 0, | ||
fontWeight: 400, | ||
lineHeight: 1.2, | ||
}, | ||
}; | ||
|
||
export default commonStyles; |
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 @@ | ||
{ | ||
"host": "http://example.com" | ||
} |
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,79 @@ | ||
{ | ||
"name": "react-static-plate", | ||
"version": "0.1.0", | ||
"description": "Build static sites with React to host on Amazon S3, Github Pages, Surge et cetera", | ||
"license": "MIT", | ||
"private": true, | ||
"scripts": { | ||
"start:dev": "babel-node ./tools/dev_server.js", | ||
"start": "npm run start:dev", | ||
"clean": "rimraf build", | ||
"build:bundle": "cross-env NODE_ENV=production webpack --config ./tools/webpack.prod.config.js", | ||
"build:static": "cross-env NODE_ENV=production babel-node ./tools/build_static_entry.js", | ||
"build": "npm run clean && npm run build:bundle && npm run build:static" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015", | ||
"react", | ||
"stage-0" | ||
] | ||
}, | ||
"eslintConfig": { | ||
"parser": "babel-eslint", | ||
"extends": "airbnb", | ||
"rules": { | ||
"strict": [ | ||
2, | ||
"never" | ||
], | ||
"new-cap": 0, | ||
"global-require": 0 | ||
} | ||
}, | ||
"engines": { | ||
"node": ">=4.4" | ||
}, | ||
"dependencies": { | ||
"radium": "^0.17.1", | ||
"radium-normalize": "^2.0.3", | ||
"react": "^15.1.0", | ||
"react-dom": "^15.1.0", | ||
"react-helmet": "^3.1.0", | ||
"react-router": "^2.4.1", | ||
"rebass": "^0.2.7" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.9.0", | ||
"babel-core": "^6.9.1", | ||
"babel-eslint": "^6.0.4", | ||
"babel-loader": "^6.2.4", | ||
"babel-preset-es2015": "^6.9.0", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"cross-env": "^1.0.8", | ||
"eslint": "^2.11.1", | ||
"eslint-config-airbnb": "^9.0.1", | ||
"eslint-plugin-import": "^1.8.1", | ||
"eslint-plugin-jsx-a11y": "^1.3.0", | ||
"eslint-plugin-react": "^5.1.1", | ||
"express": "^4.13.4", | ||
"file-loader": "^0.8.5", | ||
"json-loader": "^0.5.4", | ||
"lodash": "^4.13.1", | ||
"mkdirp": "^0.5.1", | ||
"redbox-react": "^1.2.6", | ||
"rimraf": "^2.5.2", | ||
"sitemap": "^1.6.0", | ||
"url-loader": "^0.5.7", | ||
"webpack": "^1.13.1", | ||
"webpack-dev-middleware": "^1.6.1", | ||
"webpack-hot-middleware": "^2.10.0", | ||
"webpack-isomorphic-tools": "^2.3.0" | ||
}, | ||
"author": "Yannik Schweinzer", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/webyak/react-static-plate" | ||
} | ||
} |
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,66 @@ | ||
import React from 'react'; | ||
import { renderToString } from 'react-dom/server'; | ||
import { match, RouterContext } from 'react-router'; | ||
import Helmet from 'react-helmet'; | ||
|
||
import getPaths from './lib/get_paths.js'; | ||
import renderSitemap from './lib/render_sitemap.js'; | ||
import writeFile from './lib/write_file.js'; | ||
import renderDocument from './lib/render_document.js'; | ||
|
||
import config from '../config.json'; | ||
import webpackConfig from './webpack.prod.config.js'; | ||
import routes from '../client/routes.js'; | ||
|
||
/** | ||
* Build a site by rendering every route into it's own file. | ||
* @param {String} bundle Public path to bundled js file | ||
*/ | ||
const buildStatic = ({ bundle }) => { | ||
const { host } = config; | ||
const paths = getPaths(routes); | ||
// make sure the not found route is not part of the sitemap. | ||
const sitemapPaths = paths.filter(value => value !== '/*'); | ||
|
||
const sitemap = renderSitemap({ paths: sitemapPaths, hostname: host }); | ||
writeFile({ | ||
dir: webpackConfig.output.path, | ||
fileName: '/sitemap.xml', | ||
content: sitemap, | ||
}); | ||
|
||
paths.forEach(path => { | ||
match({ routes, location: path }, (error, redirectLocation, renderProps) => { | ||
if (error) throw error; | ||
|
||
if (renderProps) { | ||
const body = renderToString(<RouterContext {...renderProps} />); | ||
const { title, meta, link, script } = Helmet.rewind(); | ||
|
||
let fileName = path === '/*' | ||
? '/404' | ||
// replace trailing slash with /index | ||
: path.replace(/\/$/, '/index'); | ||
|
||
fileName = `${fileName}.html`; | ||
|
||
const html = renderDocument({ | ||
Title: title.toComponent(), | ||
metas: meta.toComponent(), | ||
links: link.toComponent(), | ||
scripts: script.toComponent(), | ||
bundle, | ||
body, | ||
}); | ||
|
||
writeFile({ | ||
dir: webpackConfig.output.path, | ||
fileName, | ||
content: html, | ||
}); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
export default buildStatic; |
Oops, something went wrong.