Clean environment, Code Splitting and Server-Side Rendering (Isomorphic/Universal) architecture with lot sugar
Hooks ready.
# Development
yarn install
yarn start
open http://localhost:3000
# Production
yarn install
yarn production
open http://localhost:5000
# Docker (Production)
docker-compose up
open http://localhost:5000
This feature allows you to split your code into various bundles which can then be loaded on demand or in parallel. - Webpack Why? Code-splitting forces you to think modular-first, your first-render bundle size surely will get a huge drop.
The magic: react-loadable
Target: Loadable Component. Currently they dont have a way to access Component.need directly (link to issue), our approach doesnt work :(, so we cant use right now.
Razzle is a tool that abstracts all complex configuration needed for SSR into a single dependency--giving you the awesome developer experience of create-react-app, but then leaving the rest of your app's architectural decisions about frameworks, routing, and data fetching up to you. Pretty customizable (babelrc, lint, webpack.config). Why? Razzle bases on CRA webpack with SSR feature and you are able to keep your own desired architecture, pretty maintenable and take off huge of your webpack dirty job.
Repo: Razzle Lib
import style from 'my.scss'
<div className={style.mycontainer} />
TODO: Style critical path in Developtment - (Pretty acceptable right now, in production this is already working because extracted css).
Once you dont have componentDidMount in server-side we need somehow abstract it. How? Flagging which dispatches we need to load before rendering our HOC (High-order-component).
fetchData() looks for RouteComponent.need (nested) additionally route/query params are accessible in .need.
- RouteComponent
- .need()
- SubRouteComponent
- .need()
Every piece of .need are synchronously resolved in every routing level. In this case above we make sure to resolve fetchTheme() before fetchPosts() PS: Same bahevior server-side/client-side
// ./containers/App.js:18
static need = ({ dispatch }, { params, query }) => [
dispatch(fetchTheme(params)),
];
// ./containers/Posts/index.js:32
static need = ({ dispatch }, { params, query }) => [
dispatch(fetchPosts(params, query)),
dispatch(fetchRatings()),
];
After first-render we need somehow resolve these RouteComponent.need at client-side. How? Manually checking for new routes and executing fetchData
// DataLoader.js:64
if (navigated) {
const { store } = this.context; // eslint-disable-line
fetchData(store, this.props.location.pathname); // eslint-disable-line
}
- Core
- Webpack 4
- React/Redux
- react-router - Declarative routing for React v4.
- Razzle Lib - SSR Webpack dirty job
- Loadable Component - Code Splitting/Lazy Loading
- Optional
- classnames - A simple JavaScript utility for conditionally joining classNames together.
- revalidator - JSON schema validator
- moment - A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
- sweetalert2 - Replacement for JavaScript's popup boxes.
- react-helmet - A document head manager for React
- Winston + exception logger
- react-router v4 stuff
- react-hot-boilerplate
- universal-react-redux-boilerplate
- isomorphic-boilerplate
- atomic react
- react-router guide
- ESLINT
- Styled component (SSR) - No mistery for this
- Style critical path in Developtment - (Pretty acceptable right now, in production this is already working because extracted css)