Porque utilizar css-modules no React
Tags: react, css, webpack
Published: 2021-03-11 18:38:17

## Motivação
Conforme o projeto vai crescendo, muitos problemas começam a surgir por decisões tomadas no início, quando aquilo não parecia ser um problema ou talvez nem fosse imaginado. Um desses problemas pode ser a falta de padrão nos estilos, e um problema que é originado a partir disso é a confusão gerada com os classNames.

## Problema
O problema com os classNames ocorre da seguinte maneira. Imaginem um nome de className bastante utilizado por todos, no caso irei explicar utilizando o nome "title". Todos os lugares em que utilizamos o "title" precisamos criar um nome composto para que não haja globalidade entre os estilos, então caso formos utilizar dentro de um card, criaremos o "card-title", caso seja uma modal, será "modal-title", e cada vez ficará mais difícil para pensar num bom nome de className para cada componente.

## Solucão
Desde a versão 2 do CRA (create-react-app) temos a opcão de criar estilos únicos para cada componente, utilizando os css-modules. Os css-modules são arquivos css em que os classNames e animações são definidos localmente, isso significa que os estilos ali criados, só serão declarados dentro daquele escopo, e não globalmente, evitando conflitos entre estilos.

## Explicação

Abaixo temos um arquivo .jsx contendo um card simples sem a utilização de css-modules:

 ```jsx
import React from 'react';
import './styles.scss';

function Card() {
  return (
    <div className="container">
      <h1 className="title">Card title</h1>
      <span className="description">Card description</span>
    </div>
  );
}

export default Card;

```

E esses são os estilos que devem ser aplicados para esse card:

```scss
.container {
  display: flex;
  flex-direction: column;
  padding: 20px;
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
}

.title {
  font-size: 18px;
  font-weight: 700;
}

.description {
  font-size: 14px;
}

```

Porém nosso card está aparecendo da seguinte forma:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3wdxijvuohiscqk5rajk.png)

Ao inspecionar, vemos que em outro lugar do projeto existe um mesmo className description que altera a cor e tamanho da fonte:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1c5e0s6eczax744bkikn.png)

A saída agora seria renomear os classNames utilizados no card, porém com os css-modules temos uma maneira melhor de fazer isso. O primeiro passo é alterar o nome do seu arquivo de estilos para o seguinte formato: `[name].module.scss`.

Depois de fazer isso, deverá alterar seu import dos estilos e a utilização dos classNames para a seguinte forma:

```jsx
import React from 'react';
import styles from './styles.module.scss';

function Card() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Card title</h1>
      <span className={styles.description}>Card description</span>
    </div>
  );
}

export default Card;
```
E então nosso componente aparecerá da seguinte forma (correta):

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lykkyoct57axfhuvy0ys.png)

Você deve estar se perguntando como que isso funciona por baixo dos panos. Bom, o css-modules cria um className único para cada local em que é utilizado, e isso é feito da seguinte forma: `[filename]\_[classname]\_\_[hash]`.

Abaixo seguem dois exemplos, um de como é compilado o card sem o css-modules, e outro com:

#### Sem css-modules
![Sem css-modules](https://dev-to-uploads.s3.amazonaws.com/i/ppucd11aqmi230e5qosm.png)

#### Com css-modules
![Com css-modules](https://dev-to-uploads.s3.amazonaws.com/i/jlo0ogdb4shn7d9b7g8j.png)

## Conclusão
Vimos que a utilização do css-modules possui muitos pontos positivos e que a sua implementação é muito simples, não precisando de um grande planejamento ou tempo, podendo fazer sua utilização para novas features e com o tempo ir aplicando nas antigas.