/react-webpack-node

Your One-Stop solution for a full-stack universal Redux App!

Primary LanguageJavaScriptMIT LicenseMIT

React Webpack Node

Dependency Status devDependency Status Gitter npm version

Deploy

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:

  • isomorphic universal 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 Router React 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:

  1. If you are working from a different machine and get heroku does not appear to be a remote repository message, be sure to run git remote add heroku git@heroku.com:appname.git.
  2. For setting up Google Authentication for Heroku and local dev, read the FAQ section

Digital Ocean

  1. Create a Droplet
  2. Follow this or this tutorial to set up nodejs
  3. Follow this tutorial to install mongodb
  4. 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 runner
    • karma.conf.js for the main karma configuration (it has webpack configurations)
    • tests.webpack.js which is the single entry file. It uses webpack's require API to find all the files we need that have a -test.js suffix.
  • mocha as the test framework
  • jsdom 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

  1. 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.
  2. What loaders do you use for ES6/ ES2015? babel-loader. Seriously, try it!
  3. Google Authentication does not work locally or on heroku!
    1. Follow these steps from Google to create your API keys on Google Developers Console
    2. 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
  1. I do not know how to write React Components/anything in ES6. Help!
    • Don't you worry child. Read this.
    • You can learn more about ES6 (or ES2015) here.

How to Contribute:

Best way to keep up to date is check the issues. I really welcome improvements for all aspects of an app.

  1. Any suggestions/improvements/bugs can be in the form of Pull Requests, or creating an issue.
  2. 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