DEV Community

Eduardo Henrique Gris
Eduardo Henrique Gris

Posted on

Biblioteca de componentes React e typescript, parte 2: padronização de código com typescript-eslint e prettier

Introdução

English version: React and typescript components lib, part 2: code standardization with typescript-eslint and prettier

No mês passado comecei a parte 1 da criação de uma biblioteca de componentes React com Typescript, focando na parte de configuração inicial e publicação. Agora nesse artigo, será incrementada a lib, com a definição de regras de padronização de código usando typescript-eslint e prettier. A ideia é colocar mais a parte prática de adição nesse artigo, para quem quiser entender mais a fundo como funciona de forma geral escrevi o artigo Typescript-eslint + prettier para padronização de código em React com Typescript no meio do mês.

Libs

typescript-eslint: responsável por analisar o código na busca e solução de problemas
prettier: responsável pela formatação de código

Setup libs

Adição do typescript-eslint, prettier e plugins que serão utilizados:

yarn add typescript-eslint eslint @eslint/js prettier eslint-plugin-react --dev

  • typescript-eslint: permite o eslint fazer parse de sintaxe typescript, traz regras de linting para typescript
  • eslint: dependência que o typescript-eslint necessita
  • @eslint/js: traz regras do eslint
  • prettier: adiciona a lib responsável pela formatação do código
  • eslint-plugin-react: traz regras de linting para React

No momento desse artigo gerou as seguintes versões:

"@eslint/js": "^9.19.0",
"eslint": "^9.19.0",
"eslint-plugin-react": "^7.37.4",
"prettier": "^3.4.2",
"typescript-eslint": "^8.23.0"
Enter fullscreen mode Exit fullscreen mode

Arquivo de configuração

Para o prettier será adicionado um arquivo na raiz da app de configuração vazio .prettierrc, por seguir as regras default dele.
Para o typescript-eslint será criado o arquivo de configuração na raiz do projeto, que vai permitir rodar a verificação do código e definir as regras que serão utilizadas para a análise. A princípio serão usadas as regras recomendadas do eslint, typescript-eslint e react:

  • 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",
      },
    }
  }
);
Enter fullscreen mode Exit fullscreen mode
  • tseslint.config: onde é passada as configurações do typescript-eslint
  • eslint.configs.recommended: aplica as regras recomendadas do eslint na análise do código
  • tseslint.configs.recommendedTypeChecked: aplica as regras recomendadas do typescript na análise do código, permitindo linting com informação de types
  • projectService: melhora a performance ao compartilhar um único serviço de análise de tipos para múltiplos arquivos
  • import.meta.dirname: indica a raiz do projeto para o parser
  • reactPlugin.configs.flat.recommended: aplica as regras recomendadas do React na análise do código
  • reactPlugin.configs.flat['jsx-runtime']: necessário para React 17+, para funcionar com o novo jsx runtime que veio a partir dessa versão
  • settings: está definido para detectar a versão de React que está sendo usada no projeto

Regras customizáveis

Tem algumas regras que acredito ser interessante modificar ou adicionar em relação as recomendadas. Para isso será necessário modificar o arquivo de configuração do typescript-eslint com a adição de 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",
    }
  }
);
Enter fullscreen mode Exit fullscreen mode
Procedência Regra Default (usando a recomendada) Com a customização
eslint no-console desabilitada habilitada, retorna aviso se tiver console.log no código
eslint no-duplicate-imports desabilitada habilitada, retorna erro se tiver imports duplicados
plugin react react/destructuring-assignment desabilitada habilitada, retorna erro se a props não estiverem desestruturadas
plugin react react/jsx-no-useless-fragment desabilitada habilitada, retorna erro se tiver fragmento desnecessário
typescript-eslint @typescript-eslint/no-unused-vars habilitada desabilitada, não retornando erro para variavéis ou parâmetros não usados

A razão para desabilitar a regra @typescript-eslint/no-unused-vars, é pela lib de componentes que está sendo criada estar acima da versão 17 do React. Com a regra habilitada retorna erro, pois na definição dos componentes da lib está definido: import React from "react";
No caso do desenvolvimento na lib, não precisaria desse import, mas se está colocando ele pois a aplicação que adicionar a lib pode estar em uma versão de React abaixo da 17, o que demanda o import estar presente. Por esse motivo foi desabilitada a regra.

package.json

No momento o package.json está da forma abaixo:

{
  "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"
  }
}
Enter fullscreen mode Exit fullscreen mode

Será adicionado scripts para garantir a padronização de código usando as regras definidas no arquivo de configuração do typescript-eslint, além disso vai ser mudada a versão para 0.2.0, uma vez que uma nova versão da lib será disponibilizada:

{
  "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"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • lint-src: vai verificar todos os arquivos dentro da pasta src (pois é onde está a definição dos componentes), seguindo as regras definidas no arquivo de configuração do typescript-eslint
  • lint-src-fix: vai autocorrigir todos os arquivos dentro da pasta src, seguindo as regras definidas no arquivo de configuração do typescript-eslint
  • format-src: vai verificar a formatação de todos os arquivos dentro da pasta src, seguindo as regras do prettier
  • format-src-fix: vai autocorrigir a formatação de todos os arquivos dentro da pasta src, seguindo as regras do prettier

Arquivo CHANGELOG

No momento o CHANGELOG.md está da forma abaixo:

## 0.1.0

_Jan. 29, 2025_

- initial config
Enter fullscreen mode Exit fullscreen mode

Como uma nova versão será disponibilizada, será adicionado sobre o que foi modificado no arquivo:

## 0.2.0

_Fev. 24, 2025_

- setup typescript-eslint and prettier
- add custom rules

## 0.1.0

_Jan. 29, 2025_

- initial config
Enter fullscreen mode Exit fullscreen mode

Estrutura de pastas

A estrutura de pastas está da seguinte forma, sendo que além da modificação de alguns arquivos, foi só adicionado dois arquivos de configuração na raiz:

Image description

Publicação nova versão

Primeiro passo a ser realizado é ver se a execução do rollup ocorre com sucesso. Para isso será executado o yarn build no terminal, que foi definido em package.json.
Executando com sucesso, é realizar a publicação da nova versão da lib: npm publish --access public

Conclusão

A ideia desse artigo foi adicionar regras de padronização de código para a lib de componentes que está sendo criada, usando typescript-eslint e prettier.
Segue o repositório no github e a lib no npmjs com as novas modificações.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay