When creating a new React project, I faced the same problems every time. I need to build it manually because create-react-app
do not provide everything that we use in real projects. We need to set up data storage, routing, configure REST, styles, etc. This was quite time-consuming, and our team decided to create some boilerplates to quick-start new projects. We’re starting to develop boilerplates for different use cases. In this article, I want to present my work to you: a boilerplate for a React
application.
Technology stack
Here's a list of libraries and dependencies used for this boilerplate. We'd decided to use minimal dependencies, and you can add anything if you need.
React-router-dom: Declarative routing for React.
Styled-components: Use the best bits of ES6 and CSS to style your apps without stress. The best CSS-in-JS library for React.
React-use: Some very simple and useful hooks for components that you can build amazing things with.
Prop-types: Runtime type checking for React props and similar objects.
Axios: The best promise-based HTTP client for Javascript.
Jest: Delightful JavaScript Testing Framework with a focus on simplicity.
Testing-library: Simple and complete testing utilities that encourage good testing practices.
ESLint+Prettier: Linter to find and fix problems in your JavaScript code. Prettier for code formatting.
📖 Delve into the technical aspects of Ember.js and React.js in this informative article, designed to equip developers with the knowledge needed to choose the best framework for their projects.
First start
Using Docker and docker-compose
This option is good in that you don't need to install a lot of dependencies on your working device. Docker just encapsulates all that trash.
To start the project with this option, you need to install Docker and docker-compose
Then, you just need to run the following command:
yarn docker:dev
When Docker installs all the necessary dependencies and builds your application, you will see Compiled successfully in your console. Your project is available on 3000 port; you can open it and start developing http://localhost:3000
Using npm
If you can't or don't want to use docker, you can use the default method for starting your project using Node.JS and npm(yarn)
1. Install dependencies
yarn # or npm i
2. Start the project
yarn start # or npm start
The application is available at http://localhost:3000
Routing
We use react-router-dom for routing in the application. All the routes are stored in the src/Router.jsx
file.
Adding a new route
To create a new route, you need to do the following steps:
Create the new file in the src/pages folder
Add the new created page in the src/pages/index.js file for better importing.
Add the new page in src/Router.jsx file
Additional information
- Documentation
- Important: The pages are used only to logically separate different parts of the application. You don't need to use the pages as components. You can use react-helmet to set up the page’s meta-tags (title, description, etc.)
Components
When you work with the components, it's recommended to use a modern approach with functional components and hooks.
It's not recommended to use class components because they work too slowly (performance) and won't be supported
To create the component, you can use the following CLI-script
:
yarn create:component MyComponent
After using this script, the folder with your component's name will appear in your src/components
folder. In this case, it will be the src/components/MyComponent
folder.
Component's files description
index.jsx — core file with logic. Example:
[ComponentName].jsx
— view file(markup). Example:
Hooks
To build logic within components, people usually use hooks.
React-use
This is a library of additional react hooks that meet most of the needs so that you do not have to reinvent the wheel every time. All hooks list
Most useful hooks:
- useDebounce — for use debounce effect in the component
- useLocalStorage — for working with localStorage in the component
- useMount — mount lifecycle hook
- useUpdateEffect — update lifecycle hook
- usePrevious — store prevState or prevProps
- useBoolean — simple state hook for boolean values
- useList — state hook for store arrays with additional utilities
Custom hooks
Creating custom hooks is a very useful thing as it allows reusing large amounts of code. If you see code that will probably be reused in the future, hook it. This is an example of using a simple custom hook implementing work with API:
Utilities
Utilities are stored in the src/utils
folder in separate files.
Available utilities
camelToSnakeCase
andsnakeToCamelCase
— transformation of a string into various styles of writing phrases without spaces or punctuationnormalizeObjectKeys
— transformation of all the object field keys usingsnakeToCamelCase
normalizeCollectionKeys
— transformation of all the elements(Element should be an object) of the array usingnormalizeObjectKeys
getRequestParams
— function for getting values of get-parameters fromlocation.search
localStorage
— utilities for working with localStorage
Axios
In working with API requests, the most useful library is axios with async/await
syntax.
Configuration
Axios
configuration is in the src/config/api.js
file.
Additional function setApiHeader
If you need to add a header in the existing axios instance, you can use setApiHeader
function. Example:
Always try to use async/await syntax.
Environment variables
To work with environment variables, we need to use some config files:
.env.example
— for storing examples of variables.env
— for variables
To add a new environment variable, you need to do the following steps:
- Add variables into
.env.example
file with empty value
REACT_APP_API_BASE_URL=
2. Add variable with value into .env
file.
REACT_APP_API_BASE_URL=https://google.com/api
3. Restart the project (required)
4. Add the variable into the config (src/config/index.js
) and use it from config
Don't forget to restart the project after adding/updating any variables
Environment variables should be ALWAYS started by REACT_APP_ ; otherwise, they won’t work
Styles
To write styles, we can use several approaches:
- Scss/BEM — default styling
- Css-In-JS (styled-components) — a recommended option that is simpler and more convenient than the previous one.
Testing
In testing everything, Jest
and React-testing-library
are used.
Useful links
Unit-tests running
There are several scripts to run tests:
yarn test
— watch-modeyarn test:coverage
— watch-mode+coverageyarn test:ci
— without watch-mode + coverage + disable coloring output
Coverage
Coverage generates after running yarn test:coverage
command. You can see expanded coverage in the HTML format in the ./coverage
folder.
Unit tests also have a minimal coverage threshold. If coverage is less than 80%, the tests will fail
Formatting
Linters are to keep code clean. They prevent shitcode from getting into a repository.
ESLint
ESLint is used for linting Javascript code.
Airbnb config is used as default.
To run a linter, you can use the following npm-scripts:
yarn lint:js
— to run a linter
yarn lint:js:fix
— to run a linter with autofix
CSS (styled-components)
To lint css code, stylelint is used. The linter checks your code for typos and spelling mistakes. To run the linter, you can use yarn lint:css
script
Find out how best to use SASS extensions for custom CSS variables here.
Airbnb styleguide links
To run both linters, you can use yarn lint:all script
JSDoc
The optimal solution to make your code more readable and cleaner is to use JSDoc. The project doesn't use JSDoc by default, but you can easily add it using the following helpful links:
Running in production
To run the project in production, you can use yarn docker:prod script. This script does the following steps:
- Download dependencies
- Build the project
- Run nginx to serve static content
Cypress
Cypress is a framework for end-to-end testing based on Javascript.
Why Cypress?
You can have 100% code coverage with unit tests, which test all your components separately, but your application can still fail when the components start to interact with each other. To prevent possible fails, you need to use e2e tests with Cypress. Cypress can test everything that works in a browser. To install cypress
, you can use the instructions in the readme
.
Typescript
To develop modern, big React
applications, people most often use Typescript
to prevent unexpected errors and problems. Typescript
helps avoid primitive errors and makes Javascript
clearer and more expressive. Typescript
has its disadvantages, but the benefits most often outweigh them. If you want to use Typescript
along with our boilerplate, you can use the instructions for adding it to a project in readme
.
Gitlab CI
Gitlab CI is one of the easiest and most convenient tools to check and deploy your code anywhere. In our boilerplate, we use several steps to make it easy to deliver your code to production:
install
— installing dependencies usingyarn
lint
— code lintingyarn lint:all
test
— running unit tests usingyarn test:ci
script; building and displaying coveragepages
— building the projectyarn build
pages:deploy
— deploy to gitlab-pages
Additional tricks
Here, I've collected a few tricks to make the development of your app easier and faster.
CLI
To create the component, you can use the following CLI-script
:
yarn create:component MyComponent
When you use this script, a folder with your component's name will appear in your src/components
folder. In this case, it will be the src/components/MyComponent
folder.
VSCode-snippets
Here is a list of available snippets to quickly create some entities:
mdocmp
— componentmdstyle
— styled-components filemdcompunit
— unit tests for componentmdpage
— pagemdhook
— custom hook
These snippets are automatically available in your VSCode
because they are set up for the project. You can see and edit any snippet in the .vscode/madboiler-snippets.code-snippets
file
Useful VSCode extensions
Here's a list of the most useful VSCode extensions that make developing your React
application easier and faster:
vscode-styled-components
— styled-components supportVisual Studio IntelliCode
— intelliSense for VSCode (AI-assit)TODO Highlight
— highlight your #todosReact PropTypes Intellisense
— intelliSense for PropTypesPrettier
— for autoformattingPath Intellisense
— intelliSense for ES6 imports/exportsESLint
— lint highlight
Сonclusion
This article shows you the boilerplate that we actively use when creating new projects. The boilerplate includes everything you need and describes some additional useful things (such as typescript and cypress). Feel free to use our boilerplate, and if you have any questions or problems with it, we promise to help you. Thanks for reading!