[Discussão] - Qual o real ponto de utilizar CSS Handles vs CSS Modules?

Olhando mais a fundo sobre os CSS Handles e sua utilização, cheguei em um ponto no qual não consegui distinguir seu uso diante de por exemplo os CSS Modules.

Exemplo:

Aqui temos uma div onde vamos definir duas classes:

  • Uma, com o nosso handle criado pelo useCssHandles(CSS_HANDLES), onde CSS_HANDLES é o nosso array de classes, e passado para o componente pelo hook useContextCssHandles() que como o nome sugere, cria um contexto com os nossos handles.
  • E a segunda sendo uma classe usada para estilizar via CSS Modules, importada logo a cima.

Com isso temos:

import React from 'react'
import { useContextCssHandles } from '../../context/CSSHandles'

import styles from './styles.modules.css'

export default () => {
  const { handles } = useContextCssHandles()
  return <div className={`${handles['container']} ${styles['container']}`}></div>
}

E o resultado que obtemos deve ser alguma coisa como:

<div class="vendor-app-0-x-container vendor-app-0-x-container"</div>

Resultado:

Bom… A mesma coisa?
Aparentemente sim, pelos testes que fiz os dois se comportam da mesma maneira, tendo HMR em apps declarados nas dependencies e (estranhamente) não quando declarados nas peerDependencies.

Gostaria de saber se alguém sabe, conhece ou gostaria de adicionar alguma coisa ao comentado. :smile:

Olá Rafael!

De fato usar a app vtex.css-handles ou usar CSS modules quando criando um componente novo vai te dar resultados praticamente iguais. As vantagens de se usar CSS Handles são relacionadas a facilidade em lidar com modificadores de classe, como a prop blockClass, que todos os blocos suportam, e valores dinâmicos usando a função applyModifiers. Se você usar CSS modules, vai precisar suportar esses modificadores por conta, sendo que a app já lida com eles pra você.

CSS Handles também foi uma forma mais declarativa de definir as classes css que consideramos API dos componentes no SF. Pra você saber facilmente quais os handles que estão disponíveis pra um dado componente/bloco, basta olhar o array de handles que ele definine. Outra coisa, como a app inteira vtex.css-handles está em TypeScript, quando você está desenvolvendo um componente usando os hooks que ela exporta, sua IDE vai te ajudar, porque ela vai saber o tipo do retorno de useCssHandles.

Outro caso de uso que pode ficar complicado sem usar o vtex.css-handles. Quando você cria um componente React que vai estar em um app vendor.app1, mas importa e renderiza um componente que vem de outra app vendor.app2. Nesse caso, como você espera que os seletores renderizados dentro do componente da app 2 sejam? Com o contexto e o hook de vtex.css-handles, você que escolhe :slight_smile: .

E por fim, uma vantagem que nos levou a considerar CSS Handles como parte da API dos nossos componentes, e sempre incentivar todo mundo a colocar handles em todas as tags HTML dentro de um componente, é que esses handles são imutáveis. E com eles conseguimos evitar que você tenha que escrever CSS no tema da loja usando seletores que estão atrelados à estrutura do HTML. Assim, mudar uma <div> pra um <span> por exemplo, não é uma breaking-change, porque a API de CSS Handles do componente continuaria a mesma.

4 Likes

Considerações:

Esse é um ponto interessante, tinha esquecido de considerar isso, com os handles por estar relacionado com o código escrito, você fica preso as classes definidas.

Esse é um ponto alto, o meu único problema com isso é que definir as classes manualmente as vezes parece como retrabalho skksks, mas o resultado final é ótimo!

Esse é um caso de uso bem especifico da plataforma, e que justifica o uso, ótimo ponto de vista.

No geral acho que eles tem funções diferentes, por mais que pareçam iguais, o handles te permite ter mais modularidade e controle com a plataforma, e o modules um desenvolvimento mais rápido.

Conclusão:

@georgebrindeiro o modelo final ideal que eu alcancei, foi através do uso do contexto do css-handles junto com um arquivo geral, onde todos os estilos são definidos.

@victor.miranda assim conseguimos uma forma simples usar os handles sem precisar iniciar novamente em cada arquivo, e ficou basicamente assim:

import { createCssHandlesContext } from 'vtex.css-handles' // Contexto
import { CssHandlesContext } from '../../typings/vtex.css-handles' // Correção de tipagem

import CSS_HANDLES from '../../constants/CSS_HANDLES'
import styles from '../../styles/index.modules.css'

// ? Magically only instantiating the modules here, applies the styles for the entire app
styles // Because ¯\_( ͡° ͜ʖ ͡°)_/¯

// ? Create the context
const { CssHandlesProvider, useContextCssHandles } = createCssHandlesContext(
  CSS_HANDLES, // Array of classes
) as CssHandlesContext<typeof CSS_HANDLES>

// ? Export the context
export { CssHandlesProvider, useContextCssHandles }

Pretendo lapidar esse modelo de forma que eu consiga definir as classes no css-modules e usa-las para iniciar o css-handles.

Ainda não encontrei uma forma de unir o prático ao agradável, mas seria ótimo alcançar isso!

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.