A painless react server side rendering koa middleware
- Stream & string mode rendering
- Gzip compression on stream & string rendering
- Rendering cache
- Styled-component & sass & less
- Cookie & token base credential
- Only few change when apply to exists or new react project
- use exists client routing
Base on project create by create-react-app & react-router-dom
-
Install packages
yarn add koa-react-carvel react react-dom react-router-dom \ koa koa-router koa-static pm2
-
Update index.js
Use App.js and render elements with hydrate or render accordingly
import React from 'react'; import ReactDOM from 'react-dom'; import Root from './App'; import * as serviceWorker from './serviceWorker'; const rootElement = document.getElementById('root'); const renderOrHydrate = rootElement.children.length ? 'hydrate' : 'render'; ReactDOM[renderOrHydrate](( <Root /> ), rootElement); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: http://bit.ly/CRA-PWA serviceWorker.unregister();
-
Create server & use koa-react-carvel middleware
server/index.js
import path from 'path'; import Koa from 'koa'; import serve from 'koa-static'; import Router from 'koa-router'; import carvel, { StreamRender } from 'koa-react-carvel'; import Root from '../src/App'; const ssrConfig = { buildPath: path.resolve('./build'), rootElementId: 'root', render: new StreamRender({ root: Root }) } const router = new Router(); router.get('/', carvel(ssrConfig)); const app = new Koa(); app.use(router.routes()); app.use(router.allowedMethods()); app.use(serve(ssrConfig.buildPath)); const port = parseInt(process.env.PORT, 10) || 4000; app.listen(port, () => { console.log(`Server has started at ${port}`); });
-
update config & add build script
add new path to config/paths.js
appSsrBuild: resolveApp('build-server'), appSsrIndexJs: resolveModule(resolveApp, 'server/index'), appSsr: resolveApp('server'),
add new script to package.json
"watch:server": "node scripts/watch-server.js", "start:server": "pm2 start --no-daemon config/pm2.server.dev.config.js", "build:server": "node scripts/build-server.js", "server": "pm2 start config/pm2.server.prod.config.js",
add new building files
add config/pm2.server.dev.config.js
add config/pm2.server.prod.config.js
add config/webpack.config.server.js
add scripts/build-server.js
add scripts/watch-server.js -
Start server & checking
npm run build npm run build:server npm run server
now ssr is working
name | require | type | description |
---|---|---|---|
buildPath | true | string | path of client build |
rootElementId | true | string | root react element of client |
render | true | object | render instance. can initialize from StringRender or StreamRender |
cache | false | object | cache instance, can initialize from MemoryCacheProvider or RedisCacheProvider |
template | false | string | html templae path,default value is 'index.html |
plugins | false | array | render plugins. currently only support stringStyledComponentsPlugin or streamStyledComponentsPlugin |
MIT © Minocoko