Configurando um projeto React com Typescript
Tags: typescript, react
Published: 2020-06-02 14:33:41

Hoje em dia o React representa uma grande fatia do desenvolvimento frontend, contendo diversas ferramentas no seu ecossistema que melhoram a experiência de desenvolvimento. Quando utilizamos o Typescript com React ganhamos a vantagem de definir bem os tipos dos nossos componentes sem o uso do PropTypes. Além disso nos beneficiamos do principio de *[fail fast](https://en.wikipedia.org/wiki/Fail-fast)*, que nos permite identificar   e evitar erros, e melhorar a qualidade do código.

Quando iniciamos um projeto React existem certas configurações como Babel e Webpack que são desejadas no projeto e podem ser configuradas manualmente. Porém, caso o seu projeto não tenha configurações bem específicas, a melhor forma de iniciar um novo projeto é utilizar um *[boiler plate](https://pt.wikipedia.org/wiki/Boilerplate_code),* como por exemplo o *"[Create React App](https://create-react-app.dev/docs/getting-started)"* , que atenderá a maioria dos casos. 

### Iniciando a aplicação com create-react-app

Para utilizar a ferramenta é necessário ter instalado o *[Node](https://nodejs.org/en/download/)* na versão 8.10 ou superior. Utilizaremos o *package runner* npx. Para criar o projeto, rode no seu terminal os comandos:

```bash
npx create-react-app my-app --template typescript
cd my-app
npm start
```

Quando criamos um novo projeto, a CLI utiliza o *Yarn* para instalar as dependência. Caso deseje utilizar *npm* basta adicionar a seguinte *flag* no comando:  `—use-npm`.

Além de configurar o Babel e o Webpack, o comando também cria a seguinte estrutura de pastas: 

```bash
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
    ├── App.css
    ├── App.tsx
    ├── App.test.tsx 
    ├── index.css
    ├── index.tsx
    ├── logo.svg
    ├── react-app-env.d.ts
    ├── serviceWorker.ts
    └── setupTests.ts
```

Caso deseje, podemos simplificar essa estrutura deletando alguns arquivos e as suas correspondentes importações.

```bash
my-app
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── index.html
│   └── robots.txt
└── src
    ├── App.tsx
    ├── index.tsx
    ├── react-app-env.d.ts
    └── setupTests.ts
```

## Adicionando ESLint

Iniciamos adicionando o ESLint como dependência de desenvolvimento:

```bash
 yarn add eslint -D
```

O próximo comando é para iniciar o ESLint

```bash
yarn eslint --init
```

No terminal a dependência faz algumas perguntas de configuração. Aqui irei colocar as minhas configurações. Você é livre para escolher outras e testar a que mais se encaixa ao seu projeto.

```bash
? How would you like to use ESLint?
> To check syntax, find problems, and enforce code style
? What type of modules does your project use?
> JavaScript modules (import/export)
? Which framework does your project use?
> React
? Does your project use TypeScript?
> y
? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to in
vert selection)
> Browser
? How would you like to define a style for your project?
> Use a popular style guide
? Which style guide do you want to follow?
> Airbnb
? What format do you want your config file to be in?
> JSON
? The style guide "airbnb" requires eslint@^5.16.0 || ^6.8.0. You are currently us
ing eslint@7.1.0. Do you want to downgrade?
> y
? Would you like to install them now with npm?
> n
```

Ao não selecionar a instalação com *npm*, o comando irá finalizar, mas antes ele gerou alguns comandos no console, que podemos copiar e rodar com *yarn*, fazendo as modificações necessárias nas versões das dependências

```bash
yarn add eslint-plugin-react@^7.19.0 @typescript-eslint/eslint-plugin@latest eslint-config-airbnb@latest eslint@^5.16.0 || ^6.8.0 eslint-plugin-import@^2.20.1 eslint-plugin-jsx-a11y@^6.2.3 eslint-plugin-react-hooks@^2.5.0 @typescript-eslint/parser@latest -D
``` 

## Adicionando Prettier

Para adicionar o Prettier e seus plugins devemos rodar no terminal o seguinte comando

```bash
yarn add prettier eslint-config-prettier eslint-plugin-prettier -D
```

Com a dependência instalada, criaremos um arquivo `prettier.config.js` que irá conter as informações de configuração do Prettier.

```bash
module.exports = {
  singleQuote: true,
  trailingComma: 'all',
  allowParens: 'avoid',
};
```

Essas configurações forçam o padrão de aspas simples, vírgula no final dos objetos e evita parenteses em arrow functions com apenas um parâmetro.

## Configurando ESLint e Prettier

Primeiramente criamos um arquivo `.eslintignore` , que inclui os arquivos onde o ESLint não irá visualizar.

```bash
**/*.js
node_modules
build
```

Agora movemos para o arquivo `.eslintrc.json` onde iremos alterar algumas regras.

Em extends iremos adicionar as dependências que instalamos

```json
"extends": [
    "plugin:react/recommended",
    "airbnb",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended"
  ],
```

Depois iremos adicionar os plugins 

```json
"plugins": ["react", "react-hooks", "@typescript-eslint", "prettier"],
```

O próximo passo é editar as regras que o ESLint irá avaliar. Entre as regras temos a permissão de código JSX dentro de arquivos .tsx e permissão de importação de arquivos .ts e .tsx sem declarar explicitamente a extensão. Você pode consultar mais regras no [link](https://eslint.org/), e pode alterar durante o desenvolvimento. Porém, cuidado com muitas modificações para não criar inconsistências no código.

```json
"rules": {
    "prettier/prettier": "error",
    "react/jsx-one-expression-per-line": "off",
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "react/jsx-filename-extension": [
      1,
      {
        "extensions": [".tsx"]
      }
    ],
    "import/prefer-default-export": "off",
    "@typescript-eslint/explicit-function-return-type": [
      "error",
      {
        "allowExpressions": true
      }
    ],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "ts": "never",
        "tsx": "never"
      }
    ]
  },
```

Para resolver as importações com Typescript primeiro devemos adicionar a dependência abaixo:

`yarn add eslint-import-resolver-typescript -D`

E por fim, para resolver as importações com Typescript adicionamos a seguinte configuração.

```json
"settings": {
    "import/resolver": {
      "typescript": {}
    }
  }
```

O resultado final da configuração do arquivo você pode conferir [nesse link](https://www.notion.so/eslintrc-json-1f1d99a3087442e1a06c81184cb9ce39)

## Adicionando EditorConfig

O [EditorConfig](https://editorconfig.org/) é um formato de  arquivo que contém regras de configuração do editor de texto e padronização de código. Em alguns editores esse arquivo é lido automaticamente e aplica as configurações. É ideal em casos onde existe uma equipe de desenvolvimento  e se deseja que todos estejam com a mesma configuração no editor de texto ou IDE de sua preferência. No [site do EditorConfig](https://editorconfig.org/) você pode conferir se há necessidade de instalar o plugin ou se o seu editor já possui suporte nativo a esse formato de arquivo

Crie um arquivo `.editorconfig` e adicione as regras de sua preferência. O arquivo final deve ser algo parecido com a configuração abaixo.

```bash
root = true

[*]
end_of_line = lf
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
```

## Extra: Configurando VSCode

Caso você utilize VSCode como o seu editor de texto, existem duas configurações que são importantes adicionar no seu arquivo `settings.json` para que o editor possa realizar a formatação automática dos arquivos ao salvar.

```json
"[typescript]": {
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
    },typescript
"[typescriptreact]": {
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
    }
  },
```

## Conclusão

O processo de configuração do React com Typescript se beneficia de *boilerplates* como o *Create React App*, onde configurações como Babel e Webpack já vem pré configuradas para nós. Na grande maioria dos projetos essas configurações são necessárias. Para padronização do código devemos configurar nossa ferramenta de linting para entender os arquivos e importações Typescript, configurar o Prettier para aplicar a formatação no código e caso o projeto seja compartilhado entre um time de desenvolvedores é interessante configurar o *EditorConfig.*

Lembrando que essas são as configurações que eu utilizo ao iniciar um novo projeto. É importante você conhecer o seu projeto e com o tempo entender quais configurações funcionam para você. Essa publicação é apenas um guia com o objetivo de facilitar o inicio do desenvolvimento. Outro ponto a se observar é que a tecnologia evolui em um ritmo acelerado, então é importante ter em mente que as configurações podem alterar com o passar do tempo.