Introduction
Portuguese version: Biblioteca de componentes React e typescript, parte 2: padronização de código com typescript-eslint e prettier
Last month, I started part 1 of creating a React component library with TypeScript, focusing on the initial setup and publishing. Now, in this article, the library will be enhanced by defining code standardization rules using typescript-eslint and prettier. The goal is to make this article more practical in terms of implementation. For those who want a deeper understanding of how it works in general, I wrote the article Typescript-eslint + prettier for code standardization in React with Typescript earlier this month.
Libs
typescript-eslint: responsible for analyzing the code to identify and resolve issues
prettier: responsible for code formatting
Setup libs
Addition of typescript-eslint, prettier and the plugins that will be used:
yarn add typescript-eslint eslint @eslint/js prettier eslint-plugin-react --dev
- typescript-eslint: allows eslint to parse typescript syntax and provides linting rules for typescript
- eslint: dependency required by typescript-eslint
- @eslint/js: provides eslint rules
- prettier: add lib responsible for code formatting
- eslint-plugin-react: brings linting rules for React
At the time of writing this article, the following versions were generated:
"@eslint/js": "^9.19.0",
"eslint": "^9.19.0",
"eslint-plugin-react": "^7.37.4",
"prettier": "^3.4.2",
"typescript-eslint": "^8.23.0"
Configuration file
For prettier a configuration file named .prettierrc
is created at the root, empty since the default rules of the library are not being modified.
For typescript-eslint a configuration file named eslint.config.mjs
is created at the root, that will allow code verification to run and define the rules that will be used for analysis. Initially, the recommended rules from eslint, typescript-eslint and react will be used:
- eslint.config.mjs
import eslint from "@eslint/js";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
{
settings: {
react: {
version: "detect",
},
}
}
);
- tseslint.config: where the typescript-eslint configurations are specified
- eslint.configs.recommended: applies the recommended eslint rules in the code analysis
- tseslint.configs.recommendedTypeChecked: applies the recommended typescript rules in the code analysis, that additionally require type information
- projectService: indicates to ask typescript's type checking service for each source file's type information
- import.meta.dirname: tells the parser the absolute path of project's root directory
- reactPlugin.configs.flat.recommended: applies the recommended React rules in the code analysis
- reactPlugin.configs.flat['jsx-runtime']: required for React 17+ to work with the new jsx runtime introduced in that version
- settings: it is set to detect the version of React being used in the project
Customization of rules
There are some rules that I believe would be interesting to modify or add compared to the recommended ones. To do this, it will be necessary to update the typescript-eslint configuration file by adding rules
:
- eslint.config.mjs
import eslint from "@eslint/js";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
{
settings: {
react: {
version: "detect",
},
},
rules: {
"no-console": "warn",
"no-duplicate-imports": "error",
"react/destructuring-assignment": "error",
"react/jsx-no-useless-fragment": "error",
"@typescript-eslint/no-unused-vars": "off",
}
}
);
Source | Rule | Default (with recommended) | With customization |
---|---|---|---|
eslint | no-console | disabled | enabled, returns a warning if there is a console.log in the code |
eslint | no-duplicate-imports | disabled | enabled, returns an error if there are duplicate imports |
plugin react | react/destructuring-assignment | disabled | enabled, returns an error if the props are not destructured |
plugin react | react/jsx-no-useless-fragment | disabled | enabled, returns an error if there is an unnecessary fragment |
typescript-eslint | @typescript-eslint/no-unused-vars | enabled | disabled, does not return an error for unused variables or parameters |
The reason for disabling the @typescript-eslint/no-unused-vars
rule is that the component library being created is above version 17 of React. With the rule enabled, an error is returned because the library component definitions include: import React from "react";
In the development of the library, this import wouldn't be necessary, but it's included because the application that adds the library may be using a version of React lower than 17, which requires the import to be present. For this reason, the rule was disabled.
package.json
For now, the package.json
should look something like the below:
{
"name": "react-example-lib",
"version": "0.1.0",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/griseduardo/react-example-lib.git"
},
"scripts": {
"build": "rollup -c --bundleConfigAsCjs",
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "11.1.6",
"@types/react": "^19.0.8",
"eslint": "^9.19.0",
"eslint-plugin-react": "^7.37.4",
"prettier": "^3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"rollup": "^4.30.1",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
"styled-components": "^6.1.14",
"typescript": "^5.7.3",
"typescript-eslint": "^8.23.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"styled-components": "^6.1.14"
}
}
Scripts will be added to ensure code standardization using the rules defined in the typescript-eslint configuration file. Additionally, the version will be changed to 0.2.0, as a new version of the library will be released:
{
"name": "react-example-lib",
"version": "0.2.0",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/griseduardo/react-example-lib.git"
},
"scripts": {
"build": "rollup -c --bundleConfigAsCjs",
"lint-src": "eslint src",
"lint-src-fix": "eslint src --fix",
"format-src": "prettier src --check",
"format-src-fix": "prettier src --write"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "11.1.6",
"@types/react": "^19.0.8",
"eslint": "^9.19.0",
"eslint-plugin-react": "^7.37.4",
"prettier": "^3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"rollup": "^4.30.1",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
"styled-components": "^6.1.14",
"typescript": "^5.7.3",
"typescript-eslint": "^8.23.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"styled-components": "^6.1.14"
}
}
- lint-src: it will check all the files inside the src folder (it is where the component definitions are located), following the rules defined in the typescript-eslint configuration file
- lint-src-fix: it will auto-correct all the files inside the src folder, following the rules defined in the typescript-eslint configuration file
- format-src: it will check all the files inside the src folder formatting, following the prettier rules
- format-src-fix: it will auto-correct the formatting for all the files inside the src folder, following the prettier rules
CHANGELOG file
For now, the CHANGELOG.md
is as follows:
## 0.1.0
_Jan. 29, 2025_
- initial config
Since a new version will be released, information about what was modified will be added in the file:
## 0.2.0
_Fev. 24, 2025_
- setup typescript-eslint and prettier
- add custom rules
## 0.1.0
_Jan. 29, 2025_
- initial config
Folder structure
The folder structure is as follows, with the modification of some files and the addition of two configuration files at the root:
Publication of a new version
The first step to be performed is to check if the rollup execution runs successfully. To do this, yarn build
will be executed in the terminal, as defined in package.json
.
If it executes successfully, proceed with publishing the new version of the library: npm publish --access public
Conclusion
The idea of this article was to add code standardization rules for the component library being created, using typescript-eslint and prettier.
Here is the repository on github and the library on npmjs with the new modifications.
Top comments (0)