![Image of Express-React-HMR-Boilerplate] (/src/public/img/logo.png)
A boilerplate for scaffolding production-ready MERN stack projects.
master | dev | |
---|---|---|
Build Status | ||
Dependency Status | - |
https://express-react-hmr-boilerplate.herokuapp.com/
- Nodejs + Express
- Reactjs + Redux + Redux-Thunk + React-Router + React-Router-Redux + Redux-Form + React-Intl
- Mongodb + Mongoose + MongoLab
- Normalizr
- Livereload
- Server-Side Rendering (SSR) & State Fetching (Isomorphic)
- Webpack + Code Splitting
- CSS Modules
- ES6/7 + Babel
- Travis CI
- Heroku Deploy Script
- PM2 for Production Serving
- Examples
- Todo List App
- List + Paginate
- Create
- Update
- Delete
- Passport
- Jwt Authentication
- Social Authentication
- i18n
- Upload avatar
- Recaptcha
- Ajax progress bar
- Google Analytics
- Admin System
- Todo List App
- React Native
Follow the commands below to integrate this boilerplate into your own project as mirror
branch.
cd <your_project>
git flow init -d
git remote add -t master mirror https://github.com/gocreating/express-react-hmr-boilerplate.git
git fetch mirror master:mirror # git fetch <remote> <rbranch>:<lbranch>
git flow feature start mirror
git merge --no-ff --no-edit mirror
git flow feature finish mirror
# git flow feature start tune-mirror
# tune the boilerplate to suit your own project
# git flow feature finish tune-mirror
git remote add origin <your_project.git>
git push -u origin master
Once there is a new version of this boilerplate, you can upgrade with the following commands
git checkout mirror
# git pull mirror dev
# ^^^^^^ ^^^ → upgrade local mirror branch from boilerplate's dev branch
# git fetch mirror dev:mirror --update-head-ok
git checkout develop
git flow feature start upgrade-mirror
git merge --no-ff --no-edit mirror
# solve conflicts
git flow feature finish upgrade-mirror
npm install -g gulp
npm install
Most services this boilerplate provides rely on mongoDB. You must config your own mongoDB URIs. The only thing you need to do is create your own configs/project/mongo/credential.js
based on the provided template configs/project/mongo/credential.tmpl.js
.
Here I take the popular gmail service as example.
- Create your own
configs/project/nodemailer/credential.js
You can check all supported services here
- Fix security issue
If you are going to run tests on travis or deploy the app on heroku, you might meet the issue that the app cannot login your gmail account from travis/heroku server. You need to manually authorize permissions to your testing/production servers.
This is also documented on nodemailer
2.1. Turn on 2-step verification
2.2. Get app passwords
2.3. Replace config's origin password with app password
TBD
TBD
TBD
- Get your API keys on reCAPTCHA
- Save keys in
configs/project/recaptcha/credential.js
.
Config Firebase (Optional)
Firebase provides 5GB/user file storage for free and is backed up by google cloud storage service. Thus we use firebase storage for free
to host user avatars.
- Follow the doc Add Firebase to your Server
- Save the credential file to
configs/project/firebase/credential.json
- Update
configs/project/firebase/client.js
-
Open Firebase console
-
Enter your app
-
Go to
Auth
page -
Click on
網路設定
and get your configuration -
Replace the following part with your configuration
var config = { apiKey: '<your-api-key>', authDomain: '<your-auth-domain>', databaseURL: '<your-database-url>', storageBucket: '<your-storage-bucket>' };
- Update
configs/project/client.js
andconfigs/project/server.js
Make sure there is a firebase
entry in each file:
// configs/project/client.js
module.exports = {
// ...
firebase: require('./firebase/client'),
// ...
};
// configs/project/server.js
module.exports = {
// ...
firebase: require('./firebase/credential.json'),
// ...
};
- Setup firebase storage security rule
We follow the doc Secure User Data, and use the following rules to restrict user permissions.
Don't forget to change the project name into your own
service firebase.storage {
match /b/express-react-hmr-boilerplate.appspot.com/o {
match /{env}/{userId}/avatar.jpg {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
For development:
gulp
For production:
gulp build:production
npm start
npm test
There are some sensitive configs inside the project, e.g., facebook app secret or firebase token, while we still need Travis to support our testing automation. Try the following command:
gulp dumpConfigs
It will show you a 3-step instruction to setup private Travis environment variables.
To sync configs on local side and on travis, you need to repeat the steps every time you update configs or tests
Deploy on Heroku
Please login heroku first, and run the command
gulp build:production
gulp deploy [--app=<heroku_app_name>] [--create]
-
-a
,--app
Specify new or existing app name of heroku. Default will be package name inside
package.json
. -
-c
,--create
If you want to create new app on heroku, please use this switch.
- Allow port 80 for both inbound and outbound
- Open terminal as
administrator
- Launch production server:
set PORT=80 && npm run pm2
See SSL FOR FREE
For development, just use:
npm run android
For production or distributing APK, please refer to the setup part of Generating Signed APK. You can use helper scripts below:
npm run android-keygen
npm run release-android
npm run install-android
We use redux-form as the infrastructure to construct all form elements. Since there is a losing focus issue, please don't render form adapters inside component's render cycle.
// working
class SomeForm extends Component {
// ...
someDollarAdapter = ({ input, ...rest }) => {
return (
<span>
<Input input={input} {...rest} /> $NTD
</span>
);
};
render() {
return (
<Form>
<Field
name="budget"
component={FormField}
label="Budget"
adapter={this.someDollarAdapter}
type="number"
/>
</Form>
);
}
};
// broken
class SomeForm extends Component {
// ...
render() {
return (
<Form>
<Field
name="budget"
component={FormField}
label="Budget"
adapter={({ input, ...rest }) => {
return (
<span>
<Input input={input} {...rest} /> $NTD
</span>
);
}}
type="number"
/>
</Form>
);
}
};
- Travis Testing (e527369)
- Disable submit button when form submitting (88557e4)
- Asynchronous redux-form validation (detect duplicate email) (4eff5b5)
- Error handling (ca4db0d)
- PM2 Integration (e427d7c)
- Rename resource as resource
s
(039baad) - Todo#Update API & Todo#Edit Functionality (daf1773)
- Pagination Mechanism (9668797)
- Bug Fix for Intl (49f085f)
- User Roles (1613ea6)
- Admin (4321886)
- Google analytics (9af2719)
- Social Auth for Facebook And LinkedIn (ccaaa60)
- Reacr-Router-Redux Integration (5e4306d)
- Use react-bootstrap in ErrorList (e44eb0b)
- Google Recaptcha (5655a29)
- Mail Service (616ca6e)
- Email Verification (5a6ef75)
- Edit User Profile (3b0b475)
- Password Recovery (91f3eb8)
- Restrict Local Upload File (size and MIME type) (0c2461f)
- Resend Verification Email (013feb4)
- Improve Testing (c6a4172)
- Add Checkbox to Agree Terms (d6b814d)
- Add
plaintext
,checkbox
,checkboxes
,textarea
,select
,rangeSlider
,airSingleDate
andairDateRange
Type Form Fields (2bbf17d) - Add Hint for Disabled Social Auth Service (813b089)
- Fix bug: Mongoose promise out of date (52cca26)
- Add Logo (a527b4f)
- Patch XSS Vulnerability (c18644b)
- Landing Page
- Translate Languages
- Add MIT License (43a5267)
- Update Packages
- Disqus Thread
- Restrict Firebase Upload File (size and MIME type)
- Information List
- Stripe Payment System + Donation Button Example
- Facebook Messenger Bot Example
- Phone Verification
- Automatically Refresh Token