Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Koa usage example
  • Loading branch information
nfantone committed Mar 11, 2018
commit cf894479a1c5521c52f10d7c64ca62034f33c894
26 changes: 26 additions & 0 deletions examples/with-koa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Using Razzle and Koa

## How to use

Download the example [or clone the whole project](https://github.com/jaredpalmer/razzle.git):

```bash
curl https://codeload.github.com/jaredpalmer/razzle/tar.gz/master | tar -xz --strip=2 razzle-master/examples/with-koa
cd with-koa
```

Install it and run:

```bash
yarn install
yarn start
```

## Idea behind the example

This is an example of how to use [Koa][koa], a web application framework, with a Razzle project, as an alternative to the default Express `server.js` setup.

Refer to the [Koa official documentation][koa-docs] for more information.

[koa]: https://koajs.com
[koa-docs]: https://github.com/koajs/koa/tree/master/docs
23 changes: 23 additions & 0 deletions examples/with-koa/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "razzle-examples-with-koa",
"version": "0.1.0",
"license": "MIT",
"scripts": {
"start": "razzle start",
"test": "razzle test --env=jsdom",
"build": "razzle build",
"start:prod": "NODE_ENV=production node build/server.js"
},
"dependencies": {
"koa": "^2.5.0",
"koa-helmet": "^3.3.0",
"koa-router": "^7.4.0",
"koa-static": "^4.0.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router-dom": "^4.2.2"
},
"devDependencies": {
"razzle": "^0.8.12"
}
}
Binary file added examples/with-koa/public/favicon.ico
Binary file not shown.
2 changes: 2 additions & 0 deletions examples/with-koa/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
User-agent: *

5 changes: 5 additions & 0 deletions examples/with-koa/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
13 changes: 13 additions & 0 deletions examples/with-koa/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import Route from 'react-router-dom/Route';
import Switch from 'react-router-dom/Switch';
import Home from './Home';
import './App.css';

const App = () => (
<Switch>
<Route exact path="/" component={Home} />
</Switch>
);

export default App;
16 changes: 16 additions & 0 deletions examples/with-koa/src/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import App from './App';
import React from 'react';
import ReactDOM from 'react-dom';
import MemoryRouter from 'react-router-dom/MemoryRouter';

describe('<App />', () => {
test('renders without exploding', () => {
const div = document.createElement('div');
ReactDOM.render(
<MemoryRouter>
<App />
</MemoryRouter>,
div
);
});
});
37 changes: 37 additions & 0 deletions examples/with-koa/src/Home.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.Home {
text-align: center;
}

.Home-logo {
animation: Home-logo-spin infinite 20s linear;
height: 80px;
}

.Home-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}

.Home-intro {
font-size: large;
}

.Home-resources {
list-style: none;
}

.Home-resources > li {
display: inline-block;
padding: 1rem;
}

@keyframes Home-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
33 changes: 33 additions & 0 deletions examples/with-koa/src/Home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import logo from './react.svg';
import './Home.css';

class Home extends React.Component {
render() {
return (
<div className="Home">
<div className="Home-header">
<img src={logo} className="Home-logo" alt="logo" />
<h2>Welcome to Razzle</h2>
</div>
<p className="Home-intro">
To get started, edit <code>src/App.js</code> or{' '}
<code>src/Home.js</code> and save to reload.
</p>
<ul className="Home-resources">
<li>
<a href="https://github.com/jaredpalmer/razzle">Docs</a>
</li>
<li>
<a href="https://github.com/jaredpalmer/razzle/issues">Issues</a>
</li>
<li>
<a href="https://palmer.chat">Community Slack</a>
</li>
</ul>
</div>
);
}
}

export default Home;
15 changes: 15 additions & 0 deletions examples/with-koa/src/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import App from './App';
import BrowserRouter from 'react-router-dom/BrowserRouter';
import React from 'react';
import { hydrate } from 'react-dom';

hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);

if (module.hot) {
module.hot.accept();
}
26 changes: 26 additions & 0 deletions examples/with-koa/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import app from './server';
import http from 'http';

const server = http.createServer(app.callback());

let currentApp = app;

server.listen(process.env.PORT || 3000, (error) => {
if (error) {
console.log(error)
}

console.log('🚀 started')
});

if (module.hot) {
console.log('✅ Server-side HMR Enabled!');

module.hot.accept('./server', () => {
console.log('🔁 HMR Reloading `./server`...');
server.removeListener('request', currentApp);
const newApp = require('./server').default;
server.on('request', newApp);
currentApp = newApp;
});
}
6 changes: 6 additions & 0 deletions examples/with-koa/src/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions examples/with-koa/src/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import App from './App';
import React from 'react';
import { StaticRouter } from 'react-router-dom';
import Koa from 'koa';
import serve from 'koa-static';
import helmet from 'koa-helmet';
import Router from 'koa-router';
import { renderToString } from 'react-dom/server';

const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);

const router = new Router();
router.get(
'/*',
(ctx, next) => {
const context = {};
const markup = renderToString(
<StaticRouter context={context} location={ctx.url}>
<App />
</StaticRouter>
);
ctx.state.markup = markup;
return context.url ? ctx.redirect(context.url) : next();
},
ctx => {
ctx.status = 200;
ctx.body = `
<!doctype html>
<html lang="">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<title>Welcome to Razzle</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
${
assets.client.css
? `<link rel="stylesheet" href="${assets.client.css}">`
: ''
}
${
process.env.NODE_ENV === 'production'
? `<script src="${assets.client.js}" defer></script>`
: `<script src="${assets.client.js}" defer crossorigin></script>`
}
</head>
<body>
<div id="root">${ctx.state.markup}</div>
</body>
</html>`;
}
);

const server = new Koa();
server
.use(helmet())
.use(serve(process.env.RAZZLE_PUBLIC_DIR))
.use(router.routes())
.use(router.allowedMethods());

export default server;
Loading