Setup inicial de aplicações ReactJs
Tags: javascript, react, eslint, prettier
Published: 2021-10-05 14:16:11

Neste post quero mostrar como configurar uma aplicação ReactJs para deixá-la padronizada para trabalho em equipes.

Primeiramente vamos criar a aplicação utilizando a **cli** `create-react-app`:
```shell
yarn create react-app nome-do-projeto --template typescript
```
## Configurando o EditorConfig
Este plugin ajuda a manter as configurações do editor iguais para todos os devs do projeto. Basta instalar a extensão `EditorConfig for VS Code` em seu **vsCode**, criar um arquivo com o nome `.editorconfig` na raiz do projeto e colar o conteúdo abaixo:
```EditorConfig
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
```
## Configurando Path Alias no projeto
para que não tenhamos que ficar importando nossos componentes utilizando `../../../../../components/Button`, vamos configurar o alias no Webpack, assim nossas importações ficará assim `@Components/Button`.

1 - Primeiramente crie um arquivo na raiz do projeto com o nome `tsconfig.paths.json` e cole o conteúdo abaixo:
```json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@Components/*": ["./src/components/*"],
      "@Sections/*": ["./src/sections/*"],
      "@Pages/*": ["./src/pages/*"],
      "@Core/*": ["./src/core/*"]
    }
  }
}
```
2 - No arquivo `tsconfig.json` na raiz do projeto, basta inserir o atributo **extends** antes de **compilerOptions**:
```json
{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {...}
}
```
3 - Para alterar as configurações padrão do **webpack** do react, precisamos instalar a biblioteca `@craco/craco`:
```shell
yarn add @craco/craco -D
```
4 - Na raiz do projeto crie um arquivo com o nome `craco.config.js` e cole o conteúdo abaixo:
```js
const path = require('path');

const config = require('./tsconfig.paths.json');

const cracoConfig = { webpack: { alias: {} } };

Object.keys(config.compilerOptions.paths).forEach((itemKey) => {
  const pathKey = itemKey.replace('/*', '');
  const pathValue = config.compilerOptions.paths[itemKey][0].replace('/*', '');
  cracoConfig.webpack.alias[pathKey] = path.resolve(__dirname, pathValue);
});

module.exports = cracoConfig;
```
5 - No arquivo `package.json` altere os **scripts** do react para:
```json
{
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  }
}
```

## Configurando o Eslint + Prettier
Para deixar o código padronizado entre os desenvolvedores do projeto, vamos utilizar o **eslint** para identificar os códigos que estão fora do padrão e o **prettier** para aplicar a formatação com base nas regras definidas pelo eslint.

1 - Instale a biblioteca `eslint` como dependência de desenvolvimento: 
```shell
yarn add eslint -D
```
2 - Execute a sequencia abaixo para configurar o `eslint` através da **cli**:
```shell
# 1 - Inicio da configuração do eslint
yarn eslint --init

# 2 - Escolha a opção "To check syntax, find problems, and enforce code style" 
How would you like to use ESLint?
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

# 3 - Escolha a opção "JavaScript modules (import/export)" 
What type of modules does your project use?
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

# 4 - Escolha a opção "React" 
Which framework does your project use?
❯ React
  Vue.js
  None of these

# 5 - Escolha a opção "Yes" 
Does your project use TypeScript?
  No
❯ Yes

# 6 - Pressionando a barra de espaço, deixe selecionado somente a opção "Browser" 
Where does your code run?
✔ Browser
  Node

# 7 - Escolha a opção "Use a popular style guide" 
How would you like to define a style for your project? … 
❯ Use a popular style guide
  Answer questions about your style
  Inspect your JavaScript file(s)

# 8 - Escolha a opção "Use a popular style guide" 
How would you like to define a style for your project? … 
❯ Use a popular style guide
  Answer questions about your style
  Inspect your JavaScript file(s)

# 9 - Escolha a opção "Airbnb" 
Which style guide do you want to follow?
❯ Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google
  XO: https://github.com/xojs/eslint-config-xo

# 10 - Escolha a opção "JavaScript" 
What format do you want your config file to be in? … 
❯ JavaScript
  YAML
  JSON

# 11 - Escolha a opção "Yes" 
Would you like to install them now with npm?
  No
❯ Yes
```

3 - Após finalizar a configuração, apague os arquivos `package-lock.json`, `yarn.lock` e a pasta `node_modules`. Agora execute o comando `yarn` para instalar e atualizar as referências de todas as bibliotecas.

4 - Agora vamos instalar o restante das dependências para o `eslint` e para o `prettier`:
```shell
yarn add prettier eslint-config-prettier eslint-plugin-prettier babel-eslint eslint-plugin-import-helpers eslint-import-resolver-alias -D
```
5 - No arquivo `.eslint.js`, cole o conteúdo abaixo:
```js
const path = require('path');

const config = require('./tsconfig.paths.json');

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  parser: '@typescript-eslint/parser',
  extends: [
    'plugin:react/recommended',
    'airbnb',
    'plugin:@typescript-eslint/recommended',
    'plugin:import/typescript',
    'plugin:prettier/recommended',
  ],
  plugins: [
    'react',
    'prettier',
    '@typescript-eslint',
    'eslint-plugin-import-helpers',
  ],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  rules: {
    'prettier/prettier': 'error',
    '@typescript-eslint/no-var-requires': 'off',
    'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
    'react/react-in-jsx-scope': 'off',
    'react/jsx-one-expression-per-line': 'off',
    'no-use-before-define': 'off',
    '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    'import-helpers/order-imports': [
      'warn',
      {
        newlinesBetween: 'always',
        groups: [
          ['/^react/'],
          ['module'],
          ['/^~//'],
          ['parent', 'sibling', 'index'],
        ],
        alphabetize: { order: 'asc', ignoreCase: true },
      },
    ],
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],
  },
  settings: {
    'import/resolver': {
      alias: {
        extensions: ['.js', '.ts', '.tsx', '.jsx'],
        map: Object.keys(config.compilerOptions.paths).map((itemKey) => {
          const pathKey = itemKey.replace('/*', '');
          const pathValue = config.compilerOptions.paths[itemKey][0].replace(
            '/*',
            '',
          );
          return [pathKey, path.resolve(__dirname, pathValue)];
        }),
      },
    },
  },
};
```
6 - Crie na raiz do projeto um arquivo com o nome `.prettierrc.js` e cole o conteúdo abaixo:
```js
module.exports = {
  semi: true,
  singleQuote: true,
  trailingComma: "all"
};
```
7 - Crie na raiz do projeto o arquivo `.eslintignore`, ele será responsável por ignorar alguns arquivos que não precisam ser analisados pelo eslint:
```
**/node_modules/*
**/out/*
**/dist/*
```
8 - Crie na raiz do projeto o arquivo `.prettierignore`, ele será responsável por ignorar alguns arquivos que não precisam ser formatados pelo prettier:
```
node_modules
yarn.lock
package-lock.json
public
```
## Para finalizar
Na hora de fazer commits das funcionalidades desenvolvidas, uma boa pratica é utilizar **Conventional Commits** para isto. 

Vamos garantir que ao fazer os commits o código esteja nos padrões definidos pelo eslint/prettier e que a mensagem do commit esteja na especificação do Conventional Commits.

1 - Vamos instalar algumas bibliotecas que irá nos ajudar nisso:
```shell
yarn add husky @commitlint/config-conventional @commitlint/cli -D
```
2 - Adicione estes 3 scripts no `package.json` na raiz do projeto:
```json
{
  "scripts": {
    "lint": "eslint ./",
    "lintFix": "eslint ./ --fix",
    "postinstall": "husky install"
  }
}
```
3 - Vamos criar o arquivo de configuração para o `commitlint`. Na raiz do projeto crie um arquivo com o nome `commitlint.config.js` e cole o conteúdo abaixo:
```js
module.exports = {
  extends: ['@commitlint/config-conventional']
};
```
4 - Agora vamos ativar o Husky e instalar os scripts que irá rodar antes de cada commit:
```shell
# Ativando o husky
yarn husky install

# Instalando o script para verificar eslint no pre-commit
yarn husky add .husky/pre-commit 'yarn lint'

# Instalando o script para verificar se a mensagem está na especificação do Conventional Commits
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'
```
## Pronto
Após todas as bibliotecas instaladas e configuradas, basta reiniciar seu **vsCode** e começar a codar 🤟🏻