React Webpack Node
Your One-Stop solution for a full-stack app with ES6/ES2015 React.js featuring universal Redux, React Router, React Router Redux Hot reloading, CSS modules, Express 4.x, mongoose.
Demo site:
https://react-webpack-node.herokuapp.com/
Features:
isomorphicuniversal Redux- Server-side rendering with React Router 2.x. Having server-side rendering allows you to pre-render the initial state of your components when a user (or search engine crawler) requests a page.
- Integrating Redux with React Router with
Redux Simple RouterReact Router Redux - Asynchonous Data Fetching on server-side rendering
- Server side authentication + Redirecting for components
- Hot reloading using react-transform-hmr
- Webpack for both development and production bundles. It's (in my opinion) the best bundler for JS, CSS, LESS, images, and lots more!
- CSS Modules allows for modular and reusable CSS. Say goodbye to conflicts (most of them) and global scope
- Unit Tests with webpack, karma, jsdom, mocha, & sinon
- Reducers
- Components
- Synchronous and Asynchronous Actions
- Express 4.x server with a ton of middleware
- Mongoose for MongoDB
- Procfile to enable deployment to Heroku & Docs on Salt configurations + Deployment for Digital Ocean
Easter Eggs 🥚
This boilerplate has gone through an evolution
React.js -> Facebook Flux -> Alt -> Redux
We have two implementations of universal flux:
- Redux is on our active master branch
- Alt (previously implemented) on flux/alt branch. It features iso, react-router and ImmutableJS.
Note: If you have previously used an alt implementation of this repository, please refer to this branch. I will not be updating it as frequently as master, but definitely welcome suggestions!
Motivation
The aim of this repo is to incorporate the best practices to building a non-trivial, performant, secure and quality full-stack apps with React.js and Webpack and Node (hence...react-webpack-node). However, along the way we definitely have had extensive additions to this boilerplate! I am working to document this repo extensively so it would be easy for both beginners and experts to begin dev-ing on it without pulling your hair out.
Why
Redux
I'm really a fan of this implementation of flux for state management. The main principles of having:
- a single store
- state being read-only (you have to express an intent to mutate being creating actions)
- mutations written as pure functions
make it very fun and easy to write predictable code! There's a ton of reasons why, but you should head to the Redux docs to dive in!
alt
Having isomorphic React was one of my key criteria when choosing a Flux library, which helped narrow down the scope of libraries. I found alt's implementation to be clean and simple, and like the option of allowing us to create alt instances or using singletons (and flushing the stores). I also like the direction in which alt is heading.
Instructions
Prerequisites
If you wish to run this app without installing/running a database, you can easily do so. Read more here.
Install MongoDB as your database:
# Update brew formulae
brew update
# Install MongoDB
brew install mongodb
If you hate MongoDB with a passion and would like to see a postgresql example, check reap out!
Setup your mongoDB directory
Note: Make sure you have the directory and its permissions setup (i.e. /data/db
):
sudo mkdir -p /data/db
sudo chown -R `id -u` /data/db
Run your mongoDB server
mongod
Build & Dev
Installation
# Install node modules - this includes those for production and development
# You only need to do this once :)
npm install
Development
# Starts the server with Hot Reloading
# Run webpack through webpack.config.dev.js
npm run dev
Production
Run the commands below for a production build, i.e. what is deployed to Heroku. If you are deploying to Heroku or similar, we assume that you serving the pages over HTTPS.
# Clean public folder
# Run webpack through webpack.config.prod.js
npm run build
# Start server
## Note: You need MongoDB running
npm start
Deployment
Heroku
heroku create
# Deploy to Heroku server
git push heroku master
# Database on Heroku
heroku addons:add mongohq
# or
heroku addons:add mongolab
# OPTIONAL:
# Rename if you need to
heroku app:rename <newname>
# Open Link in browser
heroku open
Note:
- If you are working from a different machine and get
heroku does not appear to be a remote repository
message, be sure to rungit remote add heroku git@heroku.com:appname.git
. - For setting up Google Authentication for Heroku and local dev, read the FAQ section
Digital Ocean
- Create a Droplet
- Follow this or this tutorial to set up nodejs
- Follow this tutorial to install mongodb
- git clone this repo
npm install
sudo npm install pm2 -g
pm2 start server/index.js
pm2 startup ubuntu
sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
Read more on DO config here
AWS
TBD - if you have an interest, please help
Unit Tests
Testing with:
karma
as test runnerkarma.conf.js
for the main karma configuration (it has webpack configurations)tests.webpack.js
which is the single entry file. It useswebpack
's require API to find all the files we need that have a-test.js
suffix.
mocha
as the test frameworkjsdom
as my test environment
# Run test once
npm test
# Run in watch mode
npm test:watch
We have unit tests for async (redux) actions, reducers, and components.
Data Flow
A simplistic representation of data flow from server to client is:
Express app.use() receives a request
-> Calls a pre-built webpack file for the server
-> Runs matching of routes in react-router for server
-> Makes async data fetching request
-> Renders Route component to string
-> Construct HTML file (with Meta, Link tags using helmet)
-> Browser receives html file with initial state
-> Client side React.JS kicks in and initializes with given state
-> Continues where it left off
-> Everyone is happy :)
More TBD
Yeoman Generator
If you like using yeoman generators, you could check out this cool yeoman generator by @iiegor!
FAQ
- Where do you compile your css? We use ExtractTextPlugin to extract compiled css in our webpack config file. Read more about postcss and Css modules here.
- What loaders do you use for ES6/ ES2015? babel-loader. Seriously, try it!
- Google Authentication does not work locally or on heroku!
- Follow these steps from Google to create your API keys on Google Developers Console
- Under APIs & Auth, Copy your Client ID and Client Secret
Dev
- For Google Auth to work locally, you need to do the following in your terminal before starting the server:
export GOOGLE_CLIENTID=YOUR_CLIENTID
export GOOGLE_SECRET=YOUR_SECRET
Heroku
- Fret not! Heroku's covered this pretty well:
heroku config:set GOOGLE_CLIENTID=YOUR_CLIENTID
heroku config:set GOOGLE_SECRET=YOUR_SECRET
heroku config:set GOOGLE_CALLBACK=YOUR_CALLBACK
- I do not know how to write React Components/anything in ES6. Help!
How to Contribute:
Best way to keep up to date is check the issues. I really welcome improvements for all aspects of an app.
- Any suggestions/improvements/bugs can be in the form of Pull Requests, or creating an issue.
- Coding guidelines:
Credits to webpack-server-side-example, example-app, flux-examples, node-express-mongo-demo, hackathon-starter, web-starter-kit, awesome material-ui, alt and iso, react-starter, reap, isomorphic-redux-app and mxstbr/react-boilerplate
License
MIT