This project introduces how to implement SSR, SPA, and PWA.
only Japanese
This project shows several implementations like below.
Name | Purpose | CSR | SSR | Note |
---|---|---|---|---|
react | view | yes | yes | |
redux | architecure | yes | yes | |
react-router | routing | yes | yes | |
react-helmet | head tag | yes | yes | |
redux-saga | side effects | yes | yes | |
styled-components | CSS in JS | yes | yes | |
loadable-components | dynamic import | yes | yes | |
apollo-boost | GraphQL | yes | yes | |
express | server side framework | N/A | yes | |
nanoid | Creating a random hash | N/A | N/A |
Name | Purpose | Note |
---|---|---|
typescript | Alt | |
webpack | a bundler for client side | |
babel | transpile typescript and loadable-components | |
storybook | preview | |
storyshots | snapshot tests | |
jest | test runner | |
testing-library | a helper to test react | |
nodemon | a watcher for server side | |
prettier | formatter | |
typescript-eslint | linter | |
workbox | service worker | |
clinic | performance profiling | |
autocannon | benchmarking tool |
See the router: src/client/router/.
This application has 3 pages and creates SPA based on redux and redux-saga.
Saga page and Apollo page use same components so you can compare each implementation.
This page reads README.md using babel-plugin-macro
.
src: src/client/components/pages/Top
This page runs just redux-saga application.
page src: src/client/components/pages/Saga
This page runs just apollo application.
page src: src/client/components/pages/Apollo
design concept: gist
src: src/client/sagas/pages.ts
All pages fork saga processes.
appProcess
loadTopPage
, loadingApolloPage
loadSagaPage
appProcess
and pages
run in parallel, also they run the same code in a server and client.
Need to call END
when running on Node.js
If you do SSR using redux-saga, you have to stop redux-saga process when all processes are finished.
try {
// fetch...
yield put(success());
} catch (err) {
yield put(failure(err));
} finally {
if (!process.env.IS_BROWSER) {
yield put(END);
}
}
src: src/server/controllers/renderer/renderer.tsx.
Use the following variables to pass data acquired by a server to the client side.
data-json
This script tag has state and data which are fetched via redux-saga, etc at the server.
<script id="initial-data" type="text/plain" data-json=...></script>
.
window.__APOLLO_STATE__
This variable has GraphQL data which are fetched at the server.
If you want to get 100 point for Best Practices, you need to set a reverse proxy server like Nginx because Express hasn't implemented http/2 yet.(also Performance)
$ git clone git@github.com:hiroppy/ssr-sample.git
$ cd ssr-sample
$ npm i
$ npm start
$ open http://localhost:3000
# GraphQL Playground
$ open http://localhost:3000/graphql
$ npm run start:storybook
$ open http://localhost:6006
$ npm test
$ npm run build # npm run build:client + npm run build:server
$ npm run start:prod # run server and use 3000
$ open http://localhost:8080
$ npm run deploy:storybook
$ npm run build
$ npm run start:prod
$ npm run benchmark # rps
Running 10s test @ http://localhost:8080
100 connections
┌─────────┬────────┬────────┬────────┬─────────┬───────────┬───────────┬────────────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼────────┼────────┼────────┼─────────┼───────────┼───────────┼────────────┤
│ Latency │ 161 ms │ 406 ms │ 829 ms │ 1277 ms │ 413.26 ms │ 191.69 ms │ 2649.38 ms │
└─────────┴────────┴────────┴────────┴─────────┴───────────┴───────────┴────────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬────────┬─────────┐
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Req/Sec │ 210 │ 210 │ 233 │ 264 │ 236.6 │ 18.87 │ 210 │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Bytes/Sec │ 3.16 MB │ 3.16 MB │ 3.51 MB │ 3.98 MB │ 3.56 MB │ 284 kB │ 3.16 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴────────┴─────────┘
Req/Bytes counts sampled once per second.
$ npm run benchmark:flame # flamegraph
This repository shows how to write and so does not introduce Atomic Design.
使用 NextJS getServerSideProps 函数的 sample code: export async function getServerSideProps(context) { // fetch data from an API const req = context.req; const res = context.res; return { props
React Server-Side Rendering Example Above is an example playground for you to play with React & Redux on Client and Server sides.Before jumping into it, make sure to read SSR tutorial on Freecodecamp
本仓库的 目的 是为 san 提供一个 SSR 代码框架和工具,以及内置了 JavaScript 的代码生成。 English SSR 代码迁移:从 san 到 san-ssr Demo:demo/ 安装 npm i san@latest san-ssr@latest san-ssr 需要 san 提供的模板字符串解析和 TypeScript 类型,因此对 san 的版本有依赖。你需要安装对应版本
Nuxt-ssr是一个文章增删改查的SSR项目 Nuxt.js该项目是一个ssr结构完整的项目,适合新人练手使用,如果对您有帮助,请右上角给个star,鼓励一下,同时希望指正。也可以加 nuxt技术交流群,大家一起相互学习,相互成长。 用到的技术 Vue.js v2.0.0 Nuxt.js v1.0.0 Node.js v9.8.0 (必须>=8.0) Express.js v4.x MongoD
使用 在SSR-3目录中 npm install 安装依赖 打包服务端 npm run server:build 打包客户端 npm run client:build 在dist目录index.ssr.html中引入客户端代码<script src="./client.bundle.js"></script> 执行服务端脚本 node server.js webpack5.0尝鲜 SSR+Vue+
无需配置即可创建React服务器端工具。 快速开始 npx create-kkt-app my-appcd my-appnpm start 您还可以从其中一个示例初始化项目。 例如kktjs/kkt-ssr。 # Using the template method# `npx create-kkt-app my-app [-e example name]`npx create-kkt-app my
⚛ React + Express – SSR Setup with TypeScript Advertising: I wrote a book about React. There's a German and an English version. Buy one if you like this project and you want to support my work! Englis