Photo by Balázs Kétyi on Unsplash

Criando uma biblioteca de Design System utilizando React

Vinnicius Gomes
iClubs
Published in
10 min readMar 24, 2022

Você sabe o que é um design system e a importância dele para nós desenvolvedores? E como implementar em um projeto?

O que é Design System?

Design System é um documento vivo com todos os componentes e suas variações de um produto ou serviço, para facilitar tanto a comunicação entre times como o desenvolvimento final do produto.

Ele facilita a manter a constância do design do produto. A ideia é que esse sistema seja utilizado para consulta, para se tomar decisões como novas features, novas interfaces e novas propriedades do produto.

Ele pode conter itens básicos como cores, tipografia, marca e até mesmo pedaços de códigos.

O Design System não é um documento estático, ele pode sofrer constantes mudanças ao longo do tempo, e essa é a ideia desse sistema, ser completamente customizável para se encaixar de diversas formas sem perder sua consistência do design.

Image by Audrey Hacq

“Design system isn’t a project, it’s a product serving products”. — Nathan Curtis

Quem usa Design System?

As principais empresas da atualidade utilizam um sistema de Design System em seus produtos. Empresas como:

“69% das empresas corporativas usam ativamente um Design System ou estão trabalhando em um!” — UXPin

Agora, vamos ao objetivo desse post

Existem algumas formas de criar um Design System para sua aplicação Frontend. Hoje vou te mostrar como criar uma biblioteca para seu Design System utilizando React.

Tecnologias que vamos utilizar:

TypeScript

TypeScript fornece segurança de tipo sobre suas funções (e componentes). Construir a biblioteca de componentes usando o TypeScript permite agrupar facilmente os tipos de seus componentes sem nenhum trabalho extra. E facilita a utilização do usuário final.

Rollup

Rollup é um empacotador de módulos para JavaScript que compila pequenos pedaços de código em algo maior e mais complexo, como uma biblioteca ou aplicativo. Ele usa o novo formato padronizado para módulos de código incluídos na revisão ES6 do JavaScript, em vez de soluções idiossincráticas anteriores, como CommonJS e AMD. Os módulos ES permitem combinar livre e perfeitamente as funções individuais mais úteis de suas bibliotecas favoritas.

Use o Webpack para aplicativos e o Rollup para bibliotecas. — Rich Harris

Vamos para o código 🤓

Primeiro vamos inicializar nosso projeto:

npm init

Você pode usar as opções padrões para todos os valores, vamos editá-los depois.

Em seguida, adicionaremos as ferramentas necessárias para criar nossos componentes:

npm install react typescript @types/react --save-dev

Configurando o TypeScript

Vamos começar configurando o TypeScript dentro da nossa biblioteca, e para fazer isso é bem simples basta rodar o comando: npx tsc --init

Após a finalização do comando, vai ser criado um arquivo chamado tsconfig.json e é nele que vai ficar toda a configuração do TypeScript.

Nesse arquivo vamos fazer uma pequena alteração:

Explicando o código adicionado:

jsx: “react” — Transforma JSX em código React
module: “ESNext” — Gera módulos JS modernos para nossa biblioteca
declaration: true — Gera um arquivo .d.ts para os types da biblioteca
declarationDir: “types” — Onde vai ficar os arquivos .d.ts
sourceMap: true — Mapeando o código JS de volta às origens do arquivo TS para depuração
outDir: “dist” — Diretório onde o projeto será gerado
moduleResolution: “node” — Siga as regras do node.js para encontrar módulos
allowSyntheticDefaultImports: true — Assume exportações padrão se nenhuma for criada manualmente
emitDeclarationOnly: true — Não gera JS (o Rollup fará isso) apenas exporta declarações de tipo

Configurando o Rollup

Agora vamos configurar o grande protagonista por fazer a nossa biblioteca funcionar!

E para começar, vamos fazer as instalações necessárias:

npm install rollup @rollup/plugin-node-resolve @rollup/plugin-typescript @rollup/plugin-commonjs rollup-plugin-dts --save-dev

Após a instalação, vamos fazer as configurações necessárias para o Rollup funcionar. Vamos criar um arquivo chamado rollup.config.js e adicionar o seguinte código:

Nesse arquivo, vamos importar os plugins que instalamos, e também o nosso package.json e vamos usar essa variável para fazer referência de alguns valores como main e module que vamos definir em breve.

A primeira coisa que vamos configurar é o nosso input, ou seja o primeiro arquivo que , que é o nosso arquivo inicial da biblioteca. Esse arquivo é o responsável por exportar tudo o que temos na biblioteca.

E também vamos iniciar três plugins, o resolve, commonjs e o typescript.

O segundo objeto de configuração define como nossos types da bibliotecas são distribuídos e usa o dts plugin para fazer isso.

E por último, precisamos definir alguns valores dentro do arquivo package.json:

{   "name": "lib",   "version": "1.0.0",   "description": "",   "scripts": {      "build": "rollup -c"   },   "author": "",   "license": "ISC",   "devDependencies": {      "@rollup/plugin-commonjs": "^21.0.2",      "@rollup/plugin-node-resolve": "^13.1.3",      "@rollup/plugin-typescript": "^8.3.1",      "@types/react": "^17.0.42",      "react": "^17.0.2",      "rollup": "^2.70.1",      "rollup-plugin-dts": "^4.2.0",      "typescript": "^4.6.2"   },   "main": "dist/cjs/index.js",   "module": "dist/esm/index.js",   "files": [      "dist"   ],   "types": "dist/index.d.ts"}

Vamos começar criando o script de build da nossa biblioteca: "build": "rollup -c" onde o -c fala para o rollup usar o nosso arquivo de configuração que criamos anteriormente.

E depois vamos adicionar as seguintes linhas:

main — Definimos o caminho de saída para os módulos CommonJS.
module — Definimos o caminho de saída para os ES6Modules.
files — Definimos o diretório de saída para a biblioteca.
types — Definimos o local para os types da biblioteca.

E pronto, o Rollup já está configurado para criar o build da nossa biblioteca.

Criando nosso primeiro componente:

Vamos criar o nosso primeiro componente do Design System, vamos criar uma pasta src dentro da raiz do projeto que vai conter a estrutura:

├── src
│ ├── lib
│ │ ├── TextField
│ │ │ ├── TextField.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ └── index.ts
└── package.json

⚠️ Os arquivos index.ts são extremamente úteis para a nossa biblioteca, eles vão facilitar as importações na hora de consumir a biblioteca. Então não se esqueça deles!

Dentro do arquivo TextField.tsx vamos ter o seguinte código:

src/lib/TextField/TextField.tsx

No arquivo src/lib/TextField/index.ts

export { default } from "./TextField";

Em seguida, exportamos esse botão do diretório de componentes src/lib/index.ts

export { default as TextField } from "./TextField";

E, finalmente, exportaremos todos os nossos componentes do diretório src base:

export * from './lib';

Criando o build da biblioteca

Agora vamos utilizar o Rollup para criar o build da nossa biblioteca de Design System. A nossa estrutura de pasta deve ser algo parecido com:

├── src
│ ├── lib
│ │ ├── TextField
│ │ │ ├── TextField.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ └── index.ts
├── package.json
├── tsconfig.json
└── rollup.config.js

E para criar o build, é simples, basta rodar o comando npm run build ou yarn build e é só aguardar…

Apos o build concluir, vai ser criado uma pasta dist que vai ficar mais ou menos assim:

Print da past dist após a execução do script “build”

E se tudo ocorreu bem, temos a nossa primeira versão da biblioteca pronta para ser publicada!

Publicando a biblioteca

Agora que a nossa biblioteca de Design System “está pronta”, precisamos publicar ela para outras pessoas poderem utilizar. Para publicar ela no NPM vamos utilizar o GitHub como hospedagem.

Então antes de mais nada, você precisa subir a sua biblioteca para um repositório no GitHub. Vou pular essa parte no post por ser uma etapa mais simples, mas caso você não souber como fazer isso da uma olhada nesse link.

Depois de ter criado o repositório, vamos criar o token no GitHub para permitir a publicação da nossa lib, e para fazer isso é bem simples:

Vá para o seu perfil do Github: Configurações -> Configurações do desenvolvedor -> Tokens de acesso pessoal. Ou basta clicar neste link

Clique em Gerar novo token. O mais importante aqui é selecionar a opção write:packages. Isso dará ao seu token permissão para ler e gravar pacotes em sua conta do Github, que é o que precisamos no momento:

Quando terminar, você pode clicar para criar o token. O Github só mostrará o token uma única vez, Então certifique-se de copiá-la para um local seguro.

Agora vamos para uma parte bem importante, precisamos configurar o nosso NPM local para publicar a nossa biblioteca.

Para fazer isso precisamos usar o arquivo .npmrc, esse é um arquivo GLOBAL, então ele não fica na raiz do nosso projeto. (Mas se você preferir, é possível deixar na raiz do projeto)

Para usuários de Mac/Linux, ele vai estar em seu diretório pessoal: ~/.npmrc

Para usuários do Windows, ele também vai para o seu diretório pessoal, embora a sintaxe seja diferente: C:\Users\{YOUR_WINDOWS_USERNAME}

Para saber mais sobre este arquivo de configuração clique aqui.

Depois de cria o arquivo, vamos colocar algumas informações nele:

registry=https://registry.npmjs.org/
@GITHUB_USERNAME:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=GITHUB_TOKEN

Precisamos alterar duas informações nesse arquivo, a primeira é o GITHUB_USERNAME onde você deve colocar o seu usuário do GitHub. A segunda informação é o GITHUB_TOKEN que é o token que geramos no GitHub.

E por último, precisamos fazer uma última alteração no arquivo de package.json. Vamos alterar o nome do nosso projeto e adicionar mais uma linha de configuração:

{
"name": "@GITHUB_USERNAME/YOUR_REPOSITORY_NAME",
"publishConfig": {
"registry": "https://npm.pkg.github.com/GITHUB_USERNAME"
},
...
}

Feito isso, nossa biblioteca já está pronta para ser publicada!

Agora é só rodar o comando npm publish e se tudo ocorrer bem, você terá sua primeira biblioteca! 🥳

Você pode conferir se tudo ocorreu bem no seu perfil do GitHub:

Utilizando a biblioteca

Para utilizar a biblioteca é simples, basta rodar o comando: npm install @GITHUB_USERNAME/YOUR_REPOSITORY_NAME

E pronto! Você já vai conseguir utilizar a biblioteca que acabamos de criar!

Otimizando a nossa biblioteca

E para otimizar ainda mais a nossa biblioteca, podemos aplicar algumas técnicas extremamente fáceis como adicionar um plugin chamado terser que reduzirá nosso pacote e reduzirá o tamanho geral do nosso arquivo.

A outra é atualizar algumas de nossas dependências para peerDependencies. Com o plugin de peerDependencies do Rollup, podemos dizer aos projetos que estão usando nossas bibliotecas quais dependências são necessárias para utilizar a nossa biblioteca, mas na verdade não agruparemos uma cópia do React com a própria biblioteca. Se a aplicação que estiver utilizando a lib já tiver o React em seu projeto, ele não vai ser instalado novamente, caso contrário, ele será instalado quando executar o npm install.

Para fazer isso é bem simples. Vamos instalar mais algumas dependências:

npm install rollup-plugin-peer-deps-external rollup-plugin-terser --save-dev

E depois vamos fazer uma modificação no arquivo rollup.config.js:

E vamos fazer uma pequena modificação no nosso package.json:

"peerDependencies": {
"react": "^17.0.2"
},

Agora vamos remover a lib react de dentro de devDependecies e passar para dentro de peerDependencies.

Adicionando estilos a biblioteca

Atualmente nossa biblioteca está sem estilo, o que não faz muito sentido para uma biblioteca de Design System. Então bora ver como configurar estilos dentro da biblioteca:

Adicionando CSS

Para adicionar o CSS precisamos configurar o Rollup para conseguir entender arquivos .css na hora da compilação.

E para fazer isso é bem simples, vamos instalar um plugin que vai nos ajudar com isso: npm install rollup-plugin-postcss --save-dev

Depois da instalação, vamos fazer uma modificação no arquivo de configuração do Rollup:

Feito isso, é possível criar arquivos .css dentro da biblioteca. E por fim vamos alterar a versão dentro do arquivo package.json:

{
"version": "0.0.2",
...
}

Por fim, rodar os comandos para publicar a biblioteca com a nova versão:

npm run rollup
npm publish

Para o post não se estender muito, não entrei no ponto de como instalar SASS ou StyledComponents dentro da nossa biblioteca, mas é muito parecido com a forma que colocamos o CSS, e existe muitos tutoriais por ai de como fazer essa configuração!

Conclusão

🥵 Ufa… Deu um pouco de trabalho, mas conseguimos terminar! Esse conteúdo é muito rico para conseguir trazer em um único post, então eu tentei trazer de uma forma simplificada como criar o seu primeiro Design System com uma estratégia que eu particularmente considero simples, mas existe inúmeras alternativas para fazer a implementação, então estude outras alternativas e veja qual se aplica melhor no seu contexto ❤️

Para ver o código utilizado no post é só clicar aqui 👈

⚠️ Criei uma estrutura mais completa utilizando React, TypeScript, Jest, Storybook, Rollup e Stitches para criar bibliotecas. Você pode consultar no GitHub clicando aqui 👈

E por hoje é isso pessoal!

Espero que tenha gostado do conteúdo, qualquer dúvida ou problema fique a vontade para entrar em contato comigo ou fazer um comentário nesse post!

Bom, é isso, espero que tenha gostado! E se tiver alguma sugestão deixe ai nos comentários 💬

Mas antes de ir, se gostou, deixe uns claps aqui no post 👏 isso me ajuda e me motiva muito!

Obrigado pela leitura!

Me acompanhe por ai! 😜

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

iClubs
iClubs

Published in iClubs

A plataforma de loyalty para você transformar clientes em fãs.

Vinnicius Gomes
Vinnicius Gomes

Written by Vinnicius Gomes

Senior Software Engineer who love to write about Frontend, JavaScript and Web development. See more about me — vinniciusgomes.dev

Responses (4)

What are your thoughts?