Basic starter kit to create an App using create-react-app and most of the best packges or tools for dates, fetching, tests, coverage, linting, formatting and more.
- Getting Started
- Prerequisites
- VS Code Plugins
- Available Scripts
- File Structure
- Naming Conventions
- Resources
For a long time I researched a good starter point to learn or to start a project with ReactJS and basic plugins, best practices, conventions, file structure, and more, I found different pieces of what I was looking for so I decided to put them all together.
So basically, what you have here is a reactjs starter project created with create-react-app
and essential configurations to start a clean and fast ReactJS App:
- Routing (ReactJs Router).
- Store Management (Redux / Modules).
- Unit testing (jest/enzyme).
- Coverage tests.
- Lint and formatting (ESLint + Airbnb + Prettier).
- Date-fns (datetime library - functional approach https://date-fns.org/).
- Solid and recommended file structure (supports containers, dumb and smart components).
- Configuration files.
- Custom scripts.
- Examples for CSS Modules, SaSS or Styled Components.
So feel free to fork and enjoy it π.
Run npm install
and then npm start
.
NodeJS https://nodejs.org/en/
My favorite IDE is VS Code so I included a list of basic plugins for ReactJS apps (if you use a different IDE I'm pretty sure there should be the same plugins for your IDE):
- ES7 React/Redux
- Jest
- ESLint
- Prettier
- EditorConfig for VS Code
- DotENV
- Auto Close Tag
- Auto Rename Tag
- Auto import - ES6
- Path Intellisense
- TODO Highlight
- vscode-styled-components
- Sass
In the project directory, you can run:
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
Launches the test runner in the interactive watch mode.
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
Note: this is a one-way operation. Once you eject
, you canβt go back!
If you arenβt satisfied with the build tool and configuration choices, you can eject
at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject
will still work, but they will point to the copied scripts so you can tweak them. At this point youβre on your own.
You donβt have to ever use eject
. The curated feature set is suitable for small and middle deployments, and you shouldnβt feel obligated to use this feature. However we understand that this tool wouldnβt be useful if you couldnβt customize it when you are ready for it.
https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
Lints all the files inside ./src
and shows the result without fixing.
Folder structure is based on productivity and some personal preferences:
src
βββ App.css * Main app styles.
βββ App.jsx * Main app component.
βββ api * Abstractions for making API requests
βββ assets * Assets that are imported into your components(images, custom svg, etc).
β βββ ...
βββ components * Components of the projects that are not the main views.
β βββ ui * Generic and reusable across the whole app. Presentational components eg. Buttons, Inputs, Checkboxes.
β βββ layout * Unique and one time use components that will help with app structure.
β βββ <domain component> * Belong to a specific domain. Reusable in different pages.
β βββ ...
βββ plugins * Init and config plugins(moment, material-ui, adal, etc).
β βββ ...
βββ index.jsx * Entry point of the application.
βββ services * All the common services. e.g. Authentication, hubs, etc.
βββ store * The Redux action types in action-type.js, reducers, selectors and main store in the sub-folders.
β βββ index.js
β βββ middlewares * Store middlewares.
β βββ sagas * Saga files in case of redux-saga.
β βββ modules * Store modules/ducks structure.
β βββ smallModule.js * Small modules can contain actions, action types, reducers and selectors in the same file.
β βββ bigModule * Big modules should be composed by separated files for actions, action types, reducer and selectors.
β βββ index.js
β βββ actions.js
β βββ ...
βββ styles/theme * All common styles (css) or theme (sass, styled-components).
βββ utils * Functions (for tests, for regex value testing, constants or filters.)
β βββ ...
βββ pages * Routed components that represents pages(Presentational Components Only).
β βββ ...
βββ .vscode * VS Code workspace settings to work with ESLint rules and formatting
(you can also lint or fix on save π).
Some important root files
.
βββ .editorconfig * Coding styles (also by programming language).
βββ .env * Environment variables (env.production, env.local, env.uat, etc).
βββ .eslintrc.json * ESLint configuration and rules.
βββ .prettierrc * Formatting Prettier options.
βββ jsconfig.json * JS compiler configurations (eg. set the root folder for roots when import files).
Here are a few important conventions:
Since JSX is not standard JS so it should go into it's own extension ie. .ts
for TypeScript, .jsx
for JSX.
Now days, most of the IDE's support both extensions for ReactJs, so more important reason today is that helps to indicate what it is: a component or plain js?.
-
Component names should always be multi-word, except for root
App
components. UseUserCard
orProfileCard
instead ofCard
for example. Each component should be in its own file.Gives more meaning and context of what the component does.
-
Components files should be always PascalCase/kebab-case except for HOC's. Use
UserCard.jsx
oruser-card.jsx
.PascalCase works best with autocompletion in code editors, as itβs consistent with how we reference components in JS(X) and templates, wherever possible. However, mixed case filenames can sometimes create issues on case-insensitive file systems, which is why kebab-case is also perfectly acceptable.
-
Components are named accordingly to it's relative path to components or src. Given that, a component located at
src/components/User/List.jsx
would be named asUserList
. A component located atsrc/screens/User/List
would be named asScreensUserList
. -
Components that are in a folder with same name, donβt repeat the name in the component. Considering that, a component located at
src/components/User/List/List.jsx
would be named asUserList
and NOT asUserListList
.The name we give to the components, should be clear and unique in the application, in order to make them being easier to find and to avoid possible confusions. Easy search inside the project.
-
Components that are only used once per page should begin with the prefix βTheβ, to denote that there can be only one. For example for a navbar or a footer you should use
TheNavbar.jsx
orTheFooter.jsx
.This does not mean the component is only used in a single page, but it will only be used once per page. These components never accept any props, since they are specific to your app, not their context within your app. If you find the need to add props, itβs a good indication that this is actually a reusable component that is only used once per page for now.
-
High Order Components (HOC) file and folder name in lowerCamelCase.
Generic convention
-
Always use full name instead of abbreviation in the name of your components. For example donβt use
UDSettings
, use insteadUserDashboardSettings
.Keep things clear
-
Each page is a react class component having some state. A page component uses other components to assemble the page like lego blocks.
Single entry point by feature or page. Keep the pages in a separated folder in the root of src, because they will be grouped accordingly to the route definition and not by modules.
-
Keep components shallow. If a components has a lot of nested markup then the chances of reusing it decreases. Instead we should take advantage of composition. It saves us from prop drilling or having to reach out to context api.
Reusable and Readable code. Passing down props to multiple child components is what they call a code smell.
-
Presentational components are those who donβt have internal state. Their role is to show certain pieces of UI or Layout. They are provided data via props or context api or state management.
-
Container components are those which deals with business logic. They usually have some state and only render presentational components based on the logic.
This way Presentational and Container components complete the puzzle together. By dividing the responsibilities, code becomes easier to maintain and debug.
- Use a central export file (Barrel export ->
index.js
) in the components directory. With this file we can just import all of our components into it and export them. This will allow us to import components into any file from the same place. - Presentational and Container components are kept at
src/components
. - Group components by
module/feature
insidecomponents folder
. - Keep generic components by context inside
src/components/ui
orsrc/components/layout
. - Keep pages simple, with minimum structure and code.
- Group pages accordingly to route definition. For a route
/user/list
we would have a page located at/src/pages/User/List.jsx
.
I got inspired by:
- Structuring projects and naming components in react
- How i structure my react apps
- Structuring a react project a definitive guide
- Is there a recommended way to structure react projects
- Applying code organization rules to concrete redux code
- Testing react redux apps with jest and enzyme
- 10 things not to do when building react applications