Recently, this boilerplate received a huge update including: GraphQL / Apollo Support, Server Rendering, Generator Refactoring, etc. If you are using this in production, you may want to use the Stable branch for a bit. See the CHANGELOG for more information of the recent updates.
The boilerplate aims to follow best practices for building highly scalable and reusable apps and component libraries with React and cutting edge JavaScript.
You can read more about the organizational strategy used in this app in this Medium post.
We incorporate an ESLint configuration and follow strictly the AirBnb JS & JSX style guides.
In most projects and frameworks, files are organized in a File type first fashion. For example, your tests exist in a test folder, your styles in a styles folder. This boilerplate takes a different approach.
We encourage encapsulation of features by asking that you organize each feature into the same folder. With React, this means that your containers and components exist in their own folders, along with literally every other file that pertains to that one component. Your actions, reducers, tests, styles, and everything else are all internal to the component they represent. By decoupling your features from the rest of your app, you set yourself up to reuse your UI components in future projects. You can thank us later!
If this is confusing, don't fret, we've set you up with a few examples and code generation tools. Give it a try! We promise you will enjoy it.
Below are a few example apps that have been built with this project
- Udacity Alumni App
- See the Code
- Live App coming soon
- RyanCollins.io v3.0
- See the Code
- Live App coming soon
- React Weekly
- Restaurant Reviewer
- Corporate Dashboard
- Meetup Event Planner
Server rendering has been merged into the master branch πππ.
Coming soon the app will support Docker, which will contain a configured web server to make deployment of this boilerplate simple! You can take a look at this branch for more details.
To try the example application out or to use the project, follow the instructions below.
There are two options for installation:
-
Clone repo
git clone https://github.com/RyanCCollins/scalable-react-boilerplate.git
-
Install dependencies
npm run setup
-
Run development server
npm run start
Your app will be served at: http://0.0.0.0:1337/
or, you can install it using Slush via the npm package
npm install -g slush slush-generator-scalable-react
cd into the folder where you want to create your project and run:
slush generator-scalable-react
Follow the onscreen instructions to create your app.
A demo ExpressJS setup is included with the app. The express server will serve up the production minified bundle.js, index.html and any other assets that are located in the /server/public
folder.
Running npm run serve:bundle
will set your environment to production and serve these files via Express. Also, a Procfile is included, which will run the Express server on Heroku when you push your code.
NOTE: the deployment script, npm run deploy
, will place all your generated assets in the server/public
folder, where they can be served in production.
To deploy with server-rendering, there is one small thing you will need to do. After your run the deploy script, go into the server/app.js
file and add the hashes for your main javascript and css bundles as shown below.
const html = (
<Html
content={content}
scriptHash="f5a35ab068d111293b63"
cssHash="6cf439ec56ba2b8700ce1665ebe17a68"
state={{ data: context.store.getState().apollo.data }}
/>
);
- Some files left out for brevity. Please reference the files in the Scalable React Boilerplate project for an example of the file structure. The application will ultimately be in use in a production web application project and more info will be posted here when we have production level examples.
.
βββ README.md
βββ LICENSE
βββ index.html
βββ package.json
βββ webpack.config.js
βββ app/
| βββ fonts
| βββ images
| βββ src
| | βββ components
| | | βββ FeatureFirstComponent
| | | | βββ index.js
| | | | βββ index.module.scss
| | | | βββ tests
| | | | | βββ index.test.js
| | | βββ App.jsx
| | | βββ Main.js
| | | βββ index.js
| | βββ containers
| | | βββ FeatureFirstContainer
| | | | βββ tests
| | | | | βββ actions.test.js
| | | | | βββ index.test.js
| | | | | βββ reducer.test.js
| | | | βββ actions.js
| | | | βββ constants.js
| | | | βββ index.js
| | | | βββ index.module.scss
| | | | βββ reducer
| | | βββ index.js
| | βββ pages
| | βββ store
| | βββ utils
| | βββ index.js
| βββ styles
βββ .eslintignore
βββ .eslintrc
βββ .gitattributes
βββ .gitignore
-
npm run setup
- Installs the application's dependencies
-
npm run test
- Runs unit tests
-
npm run test:watch
- Watches for changes to run unit tests
-
npm run build
- Bundles the application
-
npm run dev
- Starts webpack development server
-
npm run lint
- Runs the linter
-
npm run deploy
- Creates the production ready files within the
/server/public
folder
- Creates the production ready files within the
-
npm run clean
- Removes the bundled code and the production ready files
-
npm run serve:bundle
- Serve production assets from the
/server/public
folder.
- Serve production assets from the
The boilerplate contains generators for easy project scaffolding. At the moment, the generator has the following scaffold generating commands built in:
- Container
npm run generate:container
- Name: the name of the container, i.e.
Awesome
, which converts to:AwesomeContainer
- Connected / Not connected ES6 Class containers (higher order)
- SCSS Modules
- Reducers, actions and constants
- GraphQL: The generator can add collocated queries and mutations using GraphQL / ApolloClient. Accept the option to use this feature.
- Tests for all of the above
- README.md file that documents the container
- Name: the name of the container, i.e.
- Component
npm run generate:component
- Name: the name of the component, i.e.
Button
- Stateless functional components (recommended)
- ES6 class components
- SCSS modules
- Tests for all of the above
- README.md file that documents the component
- Name: the name of the component, i.e.
- Page
npm run generate:page
- Name: The name of the route, i.e. Home, which gets converted to
HomePage
- Route: the route that corresponds to the page
- Container Import: Most of the time, a Route exists only to import a container by the same name. This is enabled by default, so make sure to run the container generator if you want to use this feature.
- Name: The name of the route, i.e. Home, which gets converted to
To run the generators with a list of options, run
npm run generate
Follow the on screen prompts to select the options you wish to use.
For convenience, you can bypass the initial selection and scaffold out containers, components and pages by running
npm run generate:<type_of_component>
where <type_of_component> is one of: component, container or page.
The generators use the same feature-first file organization as the rest of the project, encapsulating components within their own folder.
In order to get the import / export to work, the generator does some pattern matching of the comments in the files to place the new imports. Just don't delete the any comment that is prefixed with GENERATOR and things will work great.
From app/src/container/index.js
or app/src/component/index.js
/* GENERATOR: Assemble all containers for export */
export LandingContainer from './LandingContainer';
export AppContainer from './AppContainer';
For information on how to build your own generators with relative ease, please go to the Plop Microgenerator homepage for detailed instructions.
Included in the setup is a test suite that will run your tests using Jest. A number of testing utilities are included, including
- Expect (Plus Expect-JSX)
- Chai (JSX and Immutable)
- Enzyme
- Jest & enzyme-to-json in order to use the Jest snappshotting with Enzyme.
You can see examples for testing of React Components, Redux Action Creators and Reducers in the repository here. Please follow the convention of naming tests with a .test.js postfix, or else the test suite will not recognize your tests.
To run tests, you will run
npm run test
which will pick up any file with the .test.js postfix and run it through Jest.
- Node - JS runtime environment
- npm - package manager
- Babel - ES6 transpiler
- Webpack - module bundler & task runner
- React - interfaces
- react-hot-loader - hot reloading for react
- react-router - react application router
- react-redux - react bindings for redux
- react-css-modules - React CSS Modules implement automatic mapping of CSS modules.
- react-foundation - Foundation React components, use or don't use.
- Immutable - data structures
- Redux - awesome flux architecture
- Redux Form- works with React Redux to enable an html form in React to use Redux to store all of its state.
- redux-thunk - thunk middleware for redux
- isomorphic-fetch - API fetch network requests
- redux-devtools - redux development tool
- SASS - styles
- ESLint - linter
- Mocha - unit tests
- jsdom - vdom to test React without browser
- Expect - assertion library
- Enzyme - React Testing utils for rendering of components
- Chai / Immutable - assertion library for Immutable JS
- A bunch of useful scripts
- Write README file
- Write component tests using Enzyme
- Implement a Rails like component generator
- Add README.md files to each component
- Add Grommet as an optional starter component library
- Add Webpack stats plugin
- Dogfood the project and iterate on suggestions
- Setup production server configuration
- Add Jest as testing utility
- Incporporate Server Rendering
- Create Docker container & automation scripts
- Write wiki / other documentation
This boilerplate began its life as a fork of the React Redux Simple Starter project and was setup as a starter project for the Udacity Alumni Web application open-source project.
It was created by several of the members of the Udacity Alumni product infrastructure team, including:
Many thanks to the team behind React Boilerplate, especially @maxstbr for setting a standard for the level of quality we in the React community can all learn from. Many of the ideas used here were reverse engineered from the same project.