In this lesson, we will walk you through the steps we followed to set up the base repo of smile-cart-frontend
, which you forked to get started with the project. This repo serves as the starting point of the SmileCart
project and contains the initial files and configurations.
As the first step in building the base application, we ran the following commands to create a React application using CRA (Create React App):
You can run the above commands, replacing smile-cart-frontend
with the application name of your choice. It will create a React application and open it in your browser at http://localhost:3000/.
We have already covered the details of setting up the React application using CRA and familiarized ourselves with the files generated by the command in the Setting up react section.
The application generated using CRA comes with predefined configurations, enabling us to concentrate on development without the necessity of learning and configuring numerous build tools. However, to make the development experience better, we would like to use advanced configurations from Webpack, Babel and ESLint.
We executed the following command to customize the application according to our requirements:
The above command exposes the configurations that were previously encapsulated inside CRA. Upon execution, it generates config
and scripts
folders in the project's root directory, housing various configurations related to our application. Additionally, the package.json
and yarn.lock
files will get updated to reflect the changes, exposing configurations related to dependencies, scripts, Jest, and Babel.
After ejecting CRA, we copied the essential configurations related to React from the Wheel. Wheel serves as the base project for setting up a Rails + React application, encapsulating the project structure and configurations adhered to at BigBinary. Given our focus on front-end development in this course, we selectively copied the files necessary for a React application. You can follow the steps mentioned below to do the same.
EditorConfig
EditorConfig is a tool that helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.
Run the following command from the project root to create editorconfig
:
Then, add the following lines to the file.
VSCode will automatically detect this configuration, and will strictly adhere to the rules mentioned in it.
ESLint
ESLint is a widely adopted JavaScript linter that analyzes and enforces coding rules and guidelines. Most of the problems ESLint finds can be automatically fixed.
Add the modules
To install the required ESLint plugins, run the following command from the terminal:
Prettier is a code formatter that can be integrated with linters. To integrate prettier with ESLint, we added eslint-config-prettier
as well as eslint-plugin-prettier
modules.
Add the config
Run the following command to fetch the required ESlint configs from wheel
:
Inorder for the ESLint to understand and analyze code written with Babel's syntax extensions, we need to specify the parser in eslintConfig
in package.json
:
Additionally, we have included babelOptions
in .eslintrc.js
file among other parser options for the ESLint to work:
Apart from adopting the ESLint configurations from Wheel, we have disabled a couple of ESLint rules that don't apply to us:
-
Before React 17, we required the import React from the "react";
statement to be present in our files to use JSX. To enforce this, we used the ESLint rule "react/react-in-jsx-scope"
. Since we are using React 18, we no longer need React import statements, and therefore, we have disabled this rule in our Project.
-
The console
statements are generally intended for debugging purposes, and their usage is discouraged in production. Nevertheless, for learning purposes, we have incorporated console.log
statements at various places in our codebase. As a result, we have disabled the "no-console"
ESLint rule in our repository.
To align our ESLint configurations with these adjustments, we can override the ESLint configurations from Wheel to disable the rules "react/react-in-jsx-scope"
and "no-console"
for our project.
The .eslintrc.js
file serves the purpose of handling ESLint configurations. However, instead of directly updating the default ESLint configurations in .eslintrc.js
, we copied its content to a file named config/eslint.js
. Subsequently, we overrode this default config from .eslintrc.js
. This way, we can neatly manage custom ESLint configurations for our project.
You can run the following command to create the config/eslint.js
file and copy the contents of .eslintrc.js
to it.
Afterwards, override the above configuration, disabling the required rules by replacing the contents of .eslintrc.js
with the code given below:
Since we are using mergeDeepLeft
from ramda
to override the defaultConfig
in the above code, we need to add ramda
to our project:
The ESLint configurations we copied from Wheel included a file named .eslintignore
. This file is used to specify the files and folders for which we don't need to run ESLint checks. We have updated the .eslintignore
file to ignore the necessary files and folders according to our project structure.
For your convenience, you can copy the configuration from smile-cart-frontend
by executing the following command:
.gitignore
The .gitignore
file specifies intentionally untracked files that need not be version-controlled using Git.
We have copied the contents of .gitignore
from Wheel and removed the entries related to Ruby files.
For convenience, you can directly copy the contents of the .gitignore
file from the smile-cart-frontend
repo by running the following command:
Prettier
Prettier is a code formatter that makes code visually appealing by enforcing a consistent and standardized style.
Add the module
Run the following command to install prettier
:
Also add the prettier plugin for tailwind using the following command:
Add the config
Run the following from the terminal to fetch the Prettier config from wheel
:
We have excluded the following line from .prettierrc.js
from the template repository since we are configuring the Tailwind CSS as part of the course itself:
VSCode recommended extensions and settings
To improve the coding experience and enhance productivity, we recommend using the following VSCode extensions:
Tailwind CSS IntelliSense: Provides autocomplete, syntax highlighting, and linting for Tailwind CSS.
EditorConfig for VS Code: Overrides user/workspace settings with settings found in .editorconfig
files.
ESLint: Integrates ESLint into VSCode, displaying errors and warnings while coding.
Code Spell Checker: Catches common spelling errors in code and documents.
GitLens: Integrates multiple Git features into VSCode.
To ensure a consistent development environment for everyone contributing to the project, we have included the list of recommended extensions in the .vscode/extensions.json
file.
Create the .vscode/extensions.json
file with the following commands:
Copy the list of recommended extensions into the .vscode/extensions.json
file:
Additionally, we have saved the following VSCode settings to automatically format your files. Create a .vscode/settings.json
file and copy the following contents:
lint-staged and husky
lint-staged
is a tool that allows us to run shell tasks on staged files. We utilized lint-staged
to run Prettier and ESLint checks on staged files to ensure that the committed code is formatted and aligns with the code guidelines.
First, add lint-staged
to devDependencies:
We specified lint-staged
as a devDependency since we only need this tool for development purposes.
Next, we specified the ESLint and Prettier commands to run on staged files in the package.json
file. Copy the relevant code from this link into your package.json
.
With these configurations, the lint-staged
command will run ESLint and Prettier checks on staged files.
To automate the execution of lint-staged
before each commit, we have set up a pre-commit
Git hook. Git hooks are scripts that run at different points in the Git workflow, such as before or after certain Git events (e.g., pre-commit
, pre-push
). We will set up the pre-commit
Git hook using husky
, which is a tool that simplifies Git hook configuration.
Run the following command to set up husky
:
The npx husky-init
command does the following things:
- Adds
husky
as a devDependency.
- Includes the
husky install
command in the prepare
script within the package.json
file. The prepare
script runs when the yarn install
command is executed, ensuring that the husky
is set up during installation.
- Generates a
.husky
directory with default configs.
husky
, by default, reads Git hooks from the .husky
directory within the project's root. We can define tasks to be executed at specific points in the Git workflow by adding a shell script with the Git event name, such as pre-commit
or pre-push
. For a shell script to be executed as a Git hook by husky
, it must have the execute permission set.
You can make a script executable by using the chmod
command:
We have added an executable shell script with the filename pre-commit
, which calls a helper function named lint_staged_files
. The helper function lint_staged_files
is defined within the .husky/helpers
folder and executes the npx lint-staged
command.
For your convenience, you can copy the pre-commit
hook from smile-cart-frontend
by executing the following commands:
In addition to the pre-commit
hook, we have configured post-merge
and post-checkout
hooks to automatically install necessary dependencies after merge and checkout operations. These hooks examine the changes in the yarn.lock
file by comparing the state of HEAD before and after a merge or checkout operation. The yarn.lock
file serves as the source of truth for the dependencies added to our project. If there are any changes in the yarn.lock
file, the yarn install
command is executed to install dependencies.
For your convenience, you can copy the scripts from smile-cart-frontend
by executing the following command:
Specifying node versions
At BigBinary, we leverage Node Version Manager (nvm) to facilitate the management of the appropriate Node.js version specific to a project. This allows us to seamlessly switch between Node.js versions as needed.
To specify the Node.js version for our smile-cart-frontend
project, we have created a .nvmrc
file in the root directory and set the Node.js version to 18.12
.
Run the following command to create the .nvmrc
file:
From now on, nvm use
, nvm install
, nvm exec
, nvm run
, and nvm
will use the version specified in the .nvmrc
file if no version is supplied on the command line.
In addition, we have also added .node-version
file specifying 18.12
as the node version.
Run the following command to create the .node-version
file:
This file is used to specify the Node.js version for version managers other than nvm. The file is kept for backward compatibility so that anyone using node version managers other than nvm can obtain the Node.js version for their version manager.
ESLINT_NO_DEV_ERRORS
By default, React displays ESLint errors as overlays during development:
Since our ESLint configurations are much stricter in terms of consistency than React's default ESLint configurations, the above feature can hinder the development process, requiring developers to address ESLint errors before seeing the output.
For instance, we enforce the import-order
rule to order import statements in our application. Most of these rules have an auto-fix feature as well. On top of this, we have a pre-commit
hook to run ESLint checks and fix auto-fixable rules before code commits. Therefore, developers need not spend their valuable time addressing such ESLint errors during development.
To streamline development and allow developers to focus on coding, we have configured the environment variable ESLINT_NO_DEV_ERRORS
to true. This setting transforms ESLint errors into warnings in the development environment, eliminating the need to fix errors immediately. Instead, the pre-commit
hook we already added will catch these errors during code commits.
You can copy the .env
file from smile-cart-frontend
to set the ESLINT_NO_DEV_ERRORS
env variable to true:
Path aliases
Consider the following import statements:
The above style of importing, where we define the import paths relative to the current file location, is called relative imports.
When navigating through a deeply nested project structure, importing files using relative imports, as shown above, can be verbose and error-prone. To alleviate this, we can sidestep the usage of relative imports by setting aliases for commonly used directories in the Webpack configuration.
Copy the highlighted lines in this link to the alias
section inside the config/webpack.config.js
file to add aliases for the commonly used directories in our project.
The absolutePath
function used in the above configuration should be defined at the top of the config/webpack.config.js
file as specified in this link.
Adding the above configuration enables us to replace relative imports with import aliases as follows:
We can add project-level configuration to VSCode using the jsconfig
file. We have defined aliases inside it to enable aliases auto imports and suggestions.
For your convenience, you can run the command below to copy jsconfig.json
file from smile-cart-frontend
to your project:
Metadata
To provide more information about our application, we have updated the content
attribute of meta
tag and title
of React application in public/index.html
. The <meta>
tag defines metadata about an HTML document such as character set, page description, keywords, author of the document and viewport settings. Metadata is used by browsers, search engines and other web services.
In addition, we updated the short_name
and name
properties of our application in public/manifest.json
to "Smile Cart". We also removed the React logos from the manifest.json
file.
Lint fixes
At last, we have fixed the ESLint errors in the files contained in src
directory by running the following command:
You may need to manually fix or disable the non-auto-fixable errors.
You can refer this commit to see the changes.