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:
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-initcommand 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.