⚛ My personal react/redux/etc webapp boilerplate and build pipeline like everyone else's, but better! ∞ ***NOT PRODUCTION READY***
My personal react/redux/etc webapp boilerplate and build pipeline like everyone else’s,
but better! (cause it gets distributed)
This repo can also pose as an example for scaling out your project for
distributed or non-distributed, multi-environment web applications.
Everyone has their own opinion on how they want their code base to look.
There are hundreds of boilerplates for a React and/or Redux application —
especially when they’re architected to solve specific problems like async
control flow or isolation of “side-effects.”
The reason for this boilerplate was to not only address various concerns
within scalable, production-ready web application, but also the code itself.
This boilerplate is meant to be an intuitive, easy to follow, scalable
and secure, modern web application boilerplate, with options to expand into
containerized micro architectures and beyond. This boilerplate is not
meant to be used completely out of the box. It is loaded with easy-to-shed
features and should be hacked and tailored to your projects needs.
Beyond initially-necessary parts of the app are commented out.
TODO
redis
redux
communication over WebSockets
docker
using docker-compose
(optional)babel
at stage-0
)tap
enzyme
for react
eslint
redux
uws
and redux-scuttlebutt
npm install
npm start
docker-compose build
docker-compose up
You’ll find an example.env
file that is nearly identical to .env
. This
contains runtime environment variables that can be read by this web application.
Variables can have values that are variables. An example in example.env
is the
Redis configuration: REDIS_HOST
, REDIS_PORT
and REDIS_AUTH
. REDIS_AUTH
is assigned the variable $REDIS_AUTH
which equates to process.env.REDIS_AUTH
.
This becomes a useful way to read sensitive data into configuration without explicitly
hardcoding it.
This web application is driven by routes
, that are tied to pages
, which
consist of modules
, that are comprised of components
This is a topic that I felt should be aligned with Unix based systems, whereby an
account can have a user id uid
; group id gid
; and be part of many groups
.
The strategy behind this, is to provide a vector for providing features (or modules
),
to subsets of accounts. In other words: feature toggling.
| uid | gid | groups | features |
| moimikey | 0 | admins, superusers | feature_a, feature_b|
| joe | 15 | users | feature_a, feature_c |
Features can be set on all groups are some groups where accounts are applicable.
URI paths (routes) in a web application are mapped to pages
. They are created
in the pages
directory and are respectively named, as they are dynamically
generated and passed to react-router
.
pages/
counter.js // http://localhost/counter
home.js // http://localhost/home
404.js // any non-route
Routes in this case are dynamically generated using the filename. In the event
of a more complex route, simple create a respectively named directory that
contains sub-routes.
pages/
counter.js
home.js
404.js
profile/
index.js // http://localhost/profile
edit.js // http://localhost/profile/edit
A page
is simply a container for modules
, which may consist of moremodules
or individual components
. A Home
page for example may consist of
many modules
like a Blog
and BlogSidebar
. These modules
are of course
comprised of components
or even more modules
.
modules
are container (smart) components. They’re contained in respectively
named directories that include relative dependencies like as actions
, reducers
,
a root component
.
modules/
MyModule/ // modules and components are capitalized
actions.js // local actions
component.js // the container (smart) component itself
component.css // accompanying CSS
index.js // exports actions, components, reducers, etc.
reducers.js // local reducers
When a module
contains a reducers.js
file, the default export is
automatically added as a globally available reducer (rootReducers
)
The state slice that the reducer will automatically bind itself to, is
equivilent to the name of the module, but lowercase. Therefore, theCounter
component has access to state.counter
while the FourOhFour
component is mapped to state.fourohfour
Use Counter
as a boilerplate module.
providers
are Higher-Order Components (HOC) for various enhancements
and are reusable:
i18n: international and local translation
featureToggle: feature toggling
Special meta properties can be used to do different things:
meta: {
debounce: 'simple' // debounce the action for 300ms
}
MIT