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.

Top comments (0)