Introdução
No mês passado comecei a parte 1 da base de criação e publicação de uma lib React com Typescript, onde vou aplicar para a lib conteúdos que escrevi no ano passado. Na próxima parte, vou definir a parte de padronização de código nela, mas ao invés de usar o que escrevi ano passado, que foram dois artigos com visão React usando eslint com prettier (um de setup e um de customização de regras), vou usar typescript-eslint com prettier na lib. Por esse motivo antes de seguir para a parte 2, estou escrevendo esse artigo com esse tema.
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 typescript-eslint
Para adicionar o typescript-eslint:
yarn add typescript-eslint eslint @eslint/js --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
Gerar arquivo de configuração na raiz do projeto:
- eslint.config.mjs
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
{
settings: {
react: {
version: "detect",
},
}
}
);
- 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.recommended: aplica as regras recomendadas do typescript na análise do código
- settings: está definido para detectar a versão de React que está sendo usada no projeto
Adição plugins
Serão adicionados as seguintes libs para aplicar as regras do React e prettier:
yarn add prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-react --dev
- prettier: adiciona a lib responsável pela formatação do código
- eslint-plugin-prettier, eslint-config-prettier: traz regras do prettier e permitem executar o prettier em conjunto com o typescript-eslint
- eslint-plugin-react: traz regras de linting para React
Adição dos plugin no arquivo de configuração do eslint:
- eslint.config.mjs
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
eslintPluginPrettierRecommended,
{
settings: {
react: {
version: "detect",
},
}
}
);
- 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
- eslintPluginPrettierRecommended: aplica as regras recomendadas do prettier para formatação do código. É necessário colocar ele por último na ordem, para desabilitar regras do eslint que conflitam com ele
Customização de regras
No momento foi realizada a configuração do typescript-eslint com prettier, aplicando as regras recomendadas dos plugins adicionados, mas dentro de um projeto parte dessas regras pode ser interessante modificar, isso é possível a partir do arquivo de configuração do eslint.
Customização prettier
Para customizar as regras do prettier, segue a seguinte estrutura:
rules: {
"prettier/prettier": [
"tipo_de_erro",
{
regra: expectativa_de_regra,
regra: expectativa_de_regra
}
]
}
- prettier/prettier: define que se está customizando uma regra do prettier
- tipo_de_erro: pode ser
warn
que retorna um aviso se a regra não for satisfeita, ou pode sererror
que retorna erro se a regra não for satisfeita - regra: corresponde a regra que vai ser customizada
- expectativa_de_regra: corresponde ao que é esperado para o código seguir
No momento, no arquivo de configuração do eslint está sendo usada as regras recomendadas do prettier, dentre elas estão algumas para não usar aspas simples para o código e jsx. Partindo de um exemplo em que no projeto se quer definir para usar as aspas simples, ficaria da seguinte forma no arquivo de configuração:
- eslint.config.mjs
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
eslintPluginPrettierRecommended,
{
settings: {
react: {
version: "detect",
},
},
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"jsxSingleQuote": true,
}
]
}
}
);
Customização eslint
Para customizar as regras do eslint, segue a seguinte estrutura:
"rules": {
regra: tipo_de_erro,
regra: [tipo_de_erro, expectativa_de_regra]
}
- regra: corresponde a regra que vai ser customizada
- tipo_de_erro: pode ser
warn
que retorna um aviso se a regra não for satisfeita, ou pode sererror
que retorna erro se a regra não for satisfeita, ou pode seroff
que desabilita a regra - expectativa_de_regra: corresponde ao que é esperado para o código seguir
No caso de ser uma regra que já tem uma expectativa na definição nela, se é passado diretamente regra: tipo_de_erro
, no caso de ser uma regra que pode ter mais de uma expectativa, se é passado regra: [tipo_de_erro, expectativa_de_regra]
definindo o que se espera dela.
No momento, no arquivo de configuração do eslint está sendo usada as regras recomendadas do eslint, typescript-eslint e react. Partindo de um exemplo em que no projeto se quer definir uma regra customizável para cada uma delas, ficaria da seguinte forma no arquivo de configuração:
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
eslintPluginPrettierRecommended,
{
settings: {
react: {
version: "detect",
},
},
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"jsxSingleQuote": true,
}
],
"no-console": "warn", // regra eslint
"react/jsx-no-useless-fragment": "error", //regra React
"@typescript-eslint/no-unused-vars": "off", // regra typescript
}
}
);
Ignorar arquivos
Terão alguns tipos de arquivos que não se deseja que rode o typescript-eslint, para isso é possível adicionar ignores
no arquivo de configuração. Passando como exemplo de uma app que ignora arquivo de documentação com storybook na padronização:
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
eslintPluginPrettierRecommended,
// as regras não se aplicarão para esses tipos de arquivo
{
ignores: ["**/*.stories.tsx"],
},
{
settings: {
react: {
version: "detect",
},
},
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"jsxSingleQuote": true,
}
],
"no-console": "warn",
"react/jsx-no-useless-fragment": "error",
"@typescript-eslint/no-unused-vars": "off",
}
}
);
Regras específicas para alguns tipos de arquivos
Além de definir arquivos para não rodar o typescript-eslint, é possível também definir regrar customizáveis específicas para arquivos específicos a partir da definição junto de files
. Partindo como exemplo de uma app que cancela uma regra para arquivos de teste:
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import reactPlugin from "eslint-plugin-react";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
eslintPluginPrettierRecommended,
{
ignores: ["**/*.stories.tsx"],
},
{
settings: {
react: {
version: "detect",
},
},
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"jsxSingleQuote": true,
}
],
"no-console": "warn",
"react/jsx-no-useless-fragment": "error",
"@typescript-eslint/no-unused-vars": "off",
}
},
// arquivos específicos com regras específicas para eles
{
files: ["**/*.test.tsx"],
rules: {
"@typescript-eslint/no-unused-expressions": "off",
},
}
);
Script package.json
Para executar o eslint e verificar o código da aplicação serão adicionados scripts no package.json:
// ...
"scripts": {
// ...
"lint": "eslint .",
"lint-fix": "eslint . --fix",
"lint-src": "eslint src",
"lint-src-fix": "eslint src --fix"
}
- lint: vai verificar todos os arquivos da aplicação, seguindo as regras definidas no arquivo de configuração do eslint
- lint-fix: vai autocorrigir o código de toda a aplicação, seguindo as regras definidas no arquivo de configuração do eslint
- lint-src: vai verificar todos os arquivos dentro da pasta src (usei src como exemplo, mas seria onde for importante dentro da app fazer essas verificações), seguindo as regras definidas no arquivo de configuração do eslint
- lint-src-fix: vai autocorrigir todos os arquivos dentro da pasta src, seguindo as regras definidas no arquivo de configuração do eslint
Problema
Diferentemente do artigo que escrevi de eslint com prettier, no momento não é possível adicionar o plugin eslint-plugin-react-hooks
para o typescript-eslint, que traz regras seguindo o que é esperado para definição dos hooks, pois tem uma issue referente a estar sem declaração de types.
Conclusão
A ideia desse artigo é apresentar como configurar o typescript-eslint com o prettier, adicionando plugins e mostrando como customizar regras. Na parte 2 da configuração da lib de componentes, será utilizado esse artigo como base e definido as regras de padronização de código.
Top comments (0)