Create React App Plus - Super Handy, Obviously Opinionated, Tested!
This is an opinionated approach to make starting a React/Redux Web Application easier, built on top of an unejected instance of Create React App. In addition to Redux, it comes with a bunch of other goodies baked in!
It's Create React App, plus a few things in place already. You can get up and building very quickly. It's not a CLI tool like Create React App, but there's not much more to it. The below assumes you're using yarn
, but you can use the corresponding npm
commands instead.
- Fork this project and check it out
- Alternatively, follow these instructions to duplicate this repository, preserve the git history, and to start multiple projects with this as a base.
- Run
yarn
to install the dependencies - That's it! Run
yarn start
to start the development server and start building!
Yup! At the heart of this is an unejected Create React App instance, you can refer to the original readme from when this was instantiated or the latest Create React App readme for how to use the built-in scripts.
This comes with a lot of things baked in and in place already. There will eventually be a code-tour doc that explains what and where everything is to make getting up and running easier, but for now... what's baked in is below
- Redux
- Modules follow a pattern similar to Redux ducks, and each should have the same structure and be in its own directory inside
src/modules
- Actions live in
index.js
, exported individually - Sagas live in
sagas.js
, exported as an array of effects - Selectors live in
selectors.js
, exported individually - Reducer live in
reducer.js
, exported as default
- Actions live in
- Reducers are combined in
src/config/reducers.js
- Reducers are mounted in
src/config/store.js
- Store is initialized and mounted in
src/index.js
- Modules follow a pattern similar to Redux ducks, and each should have the same structure and be in its own directory inside
- Redux Saga
- Sagas are combined in
src/config/sagas.js
- Sagas are mounted in
src/config/store.js
- Sagas are combined in
- React Router
- Routes are defined in
src/config/routes.js
- Routes are mounted in
src/index.js
- Uses
BrowserHistory
- Routes are defined in
- SASS
- Add your styles in
.scss
files, and import them in to components from.css
files with the same name in the same directory.- Check out how the main page imports styles
.css
files are excluded from source control and auto-generated in the build process.- For more information on how this is accomplished, see Facebook's guide to set it up
- Add your styles in
- Material UI
- Material UI is mounted in
src/index.js
- Material UI is mounted in
- Express
- Because we are using React Router with
BrowserHistory
, we need to make sure to serve the right static files regardless of what path is used to access the app. We've built a simple server to handle this. - See
server
- Because we are using React Router with
- Three different pages, in the
src/pages
directory- Default Route:
/
insrc/pages/app.js
- Todo+Gifs:
/todo
insrc/pages/todo.js
- A route-not-defined fallback in
src/pages/not-found.js
- Default Route:
- A fully tested example Redux module that powers Todo+Gifs
- Module:
src/modules/todo
- API:
src/api/todo.js
- Tests
- Module:
src/tests/modules/todo
- API:
src/tests/api/todo.test.js
- Module:
- Module:
- A sample empty module directory to demonstrate the structure in
src/modules/_blank-module
Because this uses React Router with BrowserHistory
by default, deploying this project is not as simple as deploying a standard Create React App straight out of the box. That is, it will still work if users navigate directly to the root of your app (by default, this is /crapshoot
, see where the routes are mounted in src/index.js
and the homepage
property in package.json
to update the root), but attempting to navigate to a route other than the root will not work without some form of server-side intervention to always serve the proper files.
To that end, there is a simple Express server that handles this for us built in server
, and we updated the build
script to handle moving the server and other necessary files to the build
directory for us.
{
"scripts": {
"build-css": "node-sass-chokidar src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
- "build": "npm run build-css && react-scripts build",
+ "build": "npm run build-css && react-scripts build && cp -R ./server ./.env ./build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
The server needs to read some values from the environment in order to properly build and serve things. Make sure to copy .env.dist
to a .env
file, and to fill in the appropriate values.
NODE_ENV
: If you're running this in production, setNODE_ENV
toproduction
PORT
: If noPORT
is provided, the server defaults to port3001
On your host, now that you have appropriate environment variables in place and have successfully run yarn build
, the build
directory is ready to be deployed! Navigate into the build
directory and run node server
to get it started, and that's it! Navigate to your-domain.com:PORT/your-root-route
to see your app. We recommend using forever
to keep your application running.