This repository shows you how to write SSR and SPA code using TypeScript.
業務で使える簡単な SSR + SPA のテンプレートを公開した
- how to render at server side using Node.js (/src/server)
- express
- redux-saga (side effects)
- styled-components (css)
- react-helmet (head)
- loadable-components (dynamic import)
- how to realize single page application (/src/client)
- react-router
- recompose (error handling, etc...)
- App Shell and Content (PWA)
- how to use Apollo(GraphQL) with SSR and SPA
- apollo-boost
- apollo-server-express
- react-apollo
- how to write test code and storybook
- express, react, redux, redux-saga, react-router, etc...
- how to develop in the development env and how to run the production env
- HMR of webpack
- dotenv
- manifest
- load distribution
- dynamic import
- how to measure application performance
- why-did-you-update
- autocannon
- clinic
Name | Purpose | CSR | SSR |
---|---|---|---|
react | view | yes | yes |
redux | architecure | yes | yes |
react-helmet | head tag | yes | yes |
recompose | HOC | 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 |
Name | Purpose |
---|---|
typescript, ts-node | language |
webpack | bundler |
storybook | preview |
jest | test runner |
workbox | service worker |
autocannon | benchmarking tool |
clinic | performance profiling |
src: src/server/controllers/renderer/renderer.tsx.
Use the following variables to pass data acquired by a server to the client side.
an article: https://blog.hiroppy.me/entry/loadable-components
This variable is used by loadable-component.
It has a JS asset's path of a page used at the page's entry point.
This variable has GraphQL data which are fetched at the server.
This script tag has data which are fetched via redux-saga, etc at the server.
src: src/client/components/pages/.
This application has 2 pages.
This page runs just graphql application.(excluding header
and base
)
src: src/client/components/pages/Top
- GraphQL using Apollo
- Query:
organizations
,author
- Mutation:
addOrganization
- Query:
Check window.__APOLLO_STATE__
in HTML.
This page runs just redux-saga application.
page src: src/client/components/pages/Orgs
saga src: src/client/sagas/orgs.ts
- fetching using redux-saga
Check HTML and <script id="initial-data" type="text/plain" data-json=...></script>
.
design concept: gist
src: src/client/sagas/pages.ts
These pages fork saga processes.
appProcess
- a common processing to execute on all pages(e.g. confirming login)
- pages
loadTopPage
- just stop saga when it ran at a server
loadOrgsPage
- fetching data and then stopping if it ran at a server
appProcess
and pages
run in parallel, also they run the same code in a server and client.
$ git clone git@github.com:hiroppy/ssr-sample.git
$ cd ssr-sample
$ npm i
$ npm start
$ npm start # use 3000
$ open http://localhost:3000
$ npm run start:storybook # use 6006
$ open http://localhost:6006
$ npm start
$ open http://localhost:3000/graphql
$ npm test
$ npm run build # npm run build:client + npm run build:server
$ npm run start:prod # run server and use 3000
$ open http://localhost8080
$ npm run deploy:storybook
This repository shows how to write and so does not introduce Atomic Design.