Introdução
English version: React and typescript components lib, part 7: conclusion
Chegamos na última parte da série! A ideia desse artigo é ser um encerramento, explicando a motivação da criação da série, de onde veio os assuntos que trouxe para a série e passando algumas evoluções possíveis/sugeridas.
Motivação
Durante o período que trabalho com desenvolvimento, tive bastante contato com projetos em diferentes clientes usando React com Typescript, me deparando com coisas que chamaram a minha atenção como pre-commit, autogeração de código com hygen, dentre outras, que me levantou a curiosidade de como configurar cada uma delas, como definir suas regras e como fazer o uso delas. Outra curiosidade que tinha era como se criava um lib de componentes e realizava a publicação dela, para disponibilizar para outras pessoas.
Dado esses pontos, criei um projeto pessoal de aprendizado rjs-components, no qual comecei configurando a lib com rollup, disponibilizando a lib de componentes e fui adicionando libs dentro dela que queria aprender a como configurar/usar.
Após um tempo que me aprofundei com o desenvolvimento da lib, me passou a ideia de não manter o que aprendi para mim, mas sim a compartilhar com outras pessoas, para ver se de certa forma auxiliava no aprendizado delas também. Dessa ideia veio o começo dessa série e agora chegamos no encerramento dela.
Evoluções possíveis/sugeridas
Durante a série abordei como conteúdo praticamente tudo que usei na lib que uso para estudo. Mas a medida que a quantidade de componentes vem crescendo e mudanças mais profundas acontecem com o código, vale a atenção em alguns pontos de melhoria.
- Documentação do CHANGELOG.md
Durante a série sempre foi documentado a alteração realizada em cada versão disponibilizada da lib. Porém em alguns momentos pode ocorrer não só acréscimo de coisas novas como aconteceu nessa série, mas sim remoção de props, mudança de comportamento de componentes, dentre outras.
Para isso, se torna importante mostrar com maior clareza que tipo de mudança está ocorrendo na nova versão, vou passar uma sugestão com base em um exemplo da lib de estudo que citei na motivação:
## 0.9.0
_May. 15, 2025_
### Breaking Changes
- remove textWeight Button property, but is possible to use textFontWeight
- remove textWeight IconButton property, but is possible to use textFontWeight
- remove textWeight Tag property, but is possible to use textFontWeight
- remove textWeight IconTag property, but is possible to use textFontWeight
### Major Changes
- update general Button default properties: sizes behavior, colors behavior, format behavior, border behavior
### General Changes
- update storybook and dependencies
- add focusColor props to Button
- add activeColor props to Button
- add disabledOpacity props to Button
- add border props to Button
- add hoverBorder props to Button
- add focusBorder props to Button
- add activeBorder props to Button
- update Button tests
- update Button docs
Em Breaking Changes
está citando mudanças que podem quebrar o uso dos componentes que funcionavam se usasse versões anteriores. Está citando que foi removida algumas props de componentes, então se alguém fazia uso delas, ao mudar para essa nova versão, precisa usar outras props para manter o comportamento esperado.
Em Major Changes
está citando uma mudança que não quebraria o uso do componente, mas é uma mudança grande que impacta as propriedades padrão dele.
Em General Changes
está citando mudanças que não impactam os componentes que já estão em uso, mas sim disponibilizam novas props para customizar eles.
- types semelhantes entre componentes
A medida que mais componentes vão sendo criados na lib, alguns vão compartilhar grande quantidade dos types. Ao invés de criar separadamente dentro de cada arquivo deles uma definição de types, é possível criar um arquivo que contém os types que são semelhantes entre diferentes componentes. Um exemplo da lib que citei acima, é uma arquivo chamado Common.types.ts
que possui types que são semelhantes entre mais de um componente. Um exemplo na lib é em relação ao Button
component e Tag
component:
Common.types.ts
// ...
export interface CommonButtonTagProps {
text: string;
textColor?: string;
textFontWeight?: number;
textFontSize?: string;
textFontFamily?: string;
backgroundColor?: string;
format?: "square" | "semiRounded" | "rounded";
borderRadius?: string;
size?: "small" | "medium" | "large";
padding?: string;
border?: string;
icon?: React.ReactNode;
iconPlacement?: "right" | "left";
spacing?: string;
}
export interface StyledCommonButtonTagProps {
$textColor?: string;
$textFontWeight?: number;
$textFontSize?: string;
$textFontFamily?: string;
$backgroundColor?: string;
$format?: "square" | "semiRounded" | "rounded";
$borderRadius?: string;
$size?: "small" | "medium" | "large";
$padding?: string;
$border?: string;
}
E dentro de cada componente é importado essas definições de interface e extendido elas com a propriedades que não são em comum entre os componentes.
Tag.tsx
// ...
import {
CommonButtonTagProps,
StyledCommonButtonTagProps,
} from "../Common.types";
export interface TagProps extends CommonButtonTagProps {
type?: "default" | "success" | "alert" | "error";
}
export interface StyledTagProps extends StyledCommonButtonTagProps {
$type?: "default" | "success" | "alert" | "error";
}
// ...
Button.tsx
// ...
import {
CommonButtonTagProps,
StyledCommonButtonTagProps,
} from "../Common.types";
export interface ButtonProps extends CommonButtonTagProps {
type?: "primary" | "secondary";
hoverColor?: string;
focusColor?: string;
activeColor?: string;
disabled?: boolean;
disabledOpacity?: number;
hoverBorder?: string;
focusBorder?: string;
activeBorder?: string;
onClick?: MouseEventHandler<HTMLButtonElement>;
}
export interface StyledButtonProps extends StyledCommonButtonTagProps {
$type?: "primary" | "secondary";
$hoverColor?: string;
$focusColor?: string;
$activeColor?: string;
$disabledOpacity?: number;
$hoverBorder?: string;
$focusBorder?: string;
$activeBorder?: string;
}
// ...
- husky além de pre-commit
Além do uso de pre-commit, o husky permite usar outros tipos de git hooks, como pre-push, post-commit, dentre outros. Para isso seria dentro da pasta .husky/_
puxar o git hook que quer utilizar para fora de _
, mas deixar ainda dentro de .husky
.
Uma possibilidade para quem usa convenções de commit, seria configurar uma lib como por exemplo o commitlint
, puxar o arquivo commit-msg
de .husky/_
para .husky
, e por fim definir dentro desse arquivo para rodar o commitlint
. Dessa forma, toda vez que um commit for feito vai validar se está seguindo as convenções de commit definidas para permitir ou não seguir ele.
- versionamento da lib
Durante o desenvolvimento da lib nesta série, sempre alteramos o segundo número da versão a cada mudança da lib, subindo de 0.1.0
para 0.2.0
, e assim por diante.
O número zero no início indica que está em fase inicial de desenvolvimento, podendo mudar as definições dentro da lib a qualquer momento, ainda não sendo considerada uma versão estável.
Uma vez que a lib atinge um nível de maturidade e estabilidade suficiente, a versão é atualizada para 1.0.0
, indicando que a lib está consolidada e pronta para uso em produção.
Para um entendimento melhor referente a versionamento semântico, recomendo bastante acessar https://semver.org/, que explica tudo em detalhes.
Conclusão
A ideia desse último artigo foi ser mais breve mesmo, apresentando a motivação da realização da série e coisas que podem ser observadas a medida que a lib cresce. Agradeço desde já quem acompanhou até aqui, espero que tenha sido útil para vocês.
Top comments (0)