Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: publicando pacotes no npm com versionamento semântico

React: publicando pacotes no npm com versionamento semântico

Automatizando a criação de componentes - Apresentação

Olá, estudante da Alura! O instrutor da Alura, Pedro Mello, que te dar as boas-vindas a mais um curso de React na nossa plataforma.

Audiodescrição: Pedro Mello se descreve como um homem branco. Possui olhos castanho-escuros, além de cabelos curtos e barba, ambos escuros. Usa piercings de argola no nariz e camiseta preta. Ao fudno, ambiente iluminado pelas cores rosa e azul.

O que vamos aprender?

Nesse curso, vamos trabalhar com o Storybook de um projeto chamado Alfabit, que é um design system desenvolvido sobre um monorepositório.

Também vamos construir um componente do zero e automatizar algumas das tarefas e desafios que encontramos ao trabalhar com monorepositórios e lidar com muitos pacotes simultaneamente. Por exemplo, vamos criar um template de componente e, a partir desse template, desenvolver um script para automatizar a criação de componentes.

Além de criar e documentar esse script, vamos publicar no npm, bem como automatizar a publicação e os bumps utilizando o semantic version (versionamento semântico) e a ferramenta changeset.

Quais são os pré-requisitos?

Por esse conteúdo ser um pouco mais avançado, exigirá que tenhamos um bom entendimento de JavaScript, pois vamos trabalhar com programação em Node e manipulação de arquivos. Será necessário também ter uma base sólida de React e conhecimento de TypeScript.

Caso seja preciso revisar alguns desses pontos, confira a lista de cursos de pré-requisitos.

Na sequência, vamos começar a criar nosso template de componente.

Automatizando a criação de componentes - Criando nosso pacote de componentes

Quando falamos sobre programação voltada para o front-end, não nos referimos apenas à construção de telas, criação de componentes ou estilização. Atualmente, a programação para desenvolvimento front-end engloba uma variedade de assuntos, incluindo os temas que estamos abordando neste curso.

Uma parte importante para facilitar nosso dia a dia como pessoas desenvolvedoras, seja front-end, back-end, full-stack, ou qualquer outra especialização em programação, é a automação de algumas tarefas diárias.

Conhecendo o projeto

Para iniciar nossa conversa, vamos explorar o projeto alfabit-monorepo, que é um monorepositório que inclui todo o nosso design system, contendo o Storybook e a documentação, bem como alguns tokens e componentes já desenvolvidos.

Na aba lateral esquerda do VS Code, vamos explorar as pastas do projeto. Na raiz, temos três pastas: "packages", "apps" e "scripts", sendo que a última está vazia.

Para conferir a divisão do nosso workspace, vamos abrir o arquivo pnpm-workspace.yml, onde identificamos dois pacotes que fazem parte do nosso monorepo:

Aqui está como o arquivo pnpm-workspace.yml está configurado para incluir essas pastas:

pnpm-workspace.yml:

packages:
  - 'apps/*'
  - 'packages/*'

Criando pacote de componentes

Nosso objetivo é automatizar a criação de componentes, pois o processo atual é muito manual. Precisamos criar uma nova pasta dentro de "packages", nomeá-la, criar um arquivo index.ts, o arquivo do componente, um package.json com todas as dependências, e configurar o rollup para a compilação JavaScript do projeto e dos componentes, preparando-os para publicação no npm. Por isso, um template que pudéssemos copiar e colar seria muito útil.

Vamos fazer um template para componentes, assim, teremos um modelo para criar novos componentes. No painel esquerdo, clicaremos com o botão direito dentro de "packages" e escolheremos a opção "New Folder" para criar uma nova pasta chamada "component-template".

A ideia é utilizar um dos componentes já criados dentro de "packages" como base, copiando: a pasta "src" e os arquivos package.json, rollup.config.js e tsconfig.json. Essa será a base para nosso template, que adaptaremos conforme necessário.

Começaremos pelo package.json. Usando os atalhos "Ctrl + C" e "Ctrl + V", vamos copiar o arquivo de "alfabit-button" e colá-lo em "component-template".

Primeiramente, devemos modificar o nome do template. Na parte de name, manteremos a referência do npm, mas substituiremos alfabit-button por alfabit-component.

Em description, vamos alterar a descrição para "Component do Design System Alfabit". Ressaltamos que vamos escrever "component" em inglês, ao invés de "componente" como no português.

As configurações de main, module, scripts do rollup, dependências de peer e dev e publicação permanecem as mesmas.

package.json:

{
    "name": "@cicatrizdev/alfabit-component",
    "description": "Component do Design System Alfabit",
    "author": {
        "name": "Cicatriz",
        "email": "contato@cicatriz.dev"
    },
    "license": "MIT",
    "version": "0.1.1",
    "main": "dist/index.js",
    "module": "dist/index.esm.js",
    "types": "dist/index.d.ts",
    "files": [
        "dist"
    ],
    "scripts": {
        "build": "rollup -c",
        "dev": "rollup -c -w"
    },
    "peerDependencies": {
        "react": "^17.0.0 || ^18.0.0",
        "react-dom": "^17.0.0 || ^18.0.0",
        "styled-components": "^5.0.0 || ^6.0.0"
    },
    "devDependencies": {
        "@types/react": "^18.0.0",
        "@types/styled-components": "^5.1.26",
        "react": "^18.0.0",
        "react-dom": "^18.0.0",
        "rollup": "^2.79.1",
        "rollup-plugin-typescript2": "^0.31.2",
        "styled-components": "^5.3.9",
        "tslib": "^2.8.0",
        "typescript": "^5.5.3",
        "@cicatrizdev/alfabit-tokens": "workspace:*"
    },
    "publishConfig": {
        "access": "public"
    }
}

Salvamos o arquivo modelo do package.json.

Voltamos a pasta "alfabit-button" para copiar os arquivos rollup.config.ts e tsconfig.json. Colamos esses arquivos no "component-template".

Por enquanto, o tsconfig apresentará um erro, pois ainda não terminamos de adicionar arquivos. Contudo, não precisaremos alterar nada nesses arquivos, pois as configurações são as mesmas para todos os componentes. Afinal, a forma como será gerada a build final do componente para publicação é a mesma.

Confira a configuração de ambos arquivos:

rollup.config.js:

import typescript from 'rollup-plugin-typescript2';

export default {
    input: 'src/index.ts',
    output: [
        {
            file: 'dist/index.js',
            format: 'cjs',
        },
        {
            file: 'dist/index.esm.js',
            format: 'es',
        },
    ],
    external: ['react', 'styled-components'],
    plugins: [
        typescript({
            tsconfig: './tsconfig.json',
        }),
    ],
};

tsconfig.json:

{
    "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "lib": ["dom", "esnext"],
        "jsx": "react",
        "declaration": true,
        "importHelpers": true,
        "declarationDir": "dist",
        "strict": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": ["src"],
    "exclude": ["node_modules", "dist"]
}

Próximos passos

Agora, dentro do "component-template", criaremos uma nova pasta chamada "src".

No "src" do "alfabit-button", existem três arquivos: Button.styles.ts que contém a estilização do botão; Button.tsx com a parte lógica; e index.ts que contém as exportações. Precisaremos replicar isso no nosso template, com algumas adaptações.

Na sequência, vamos continuar a criação do nosso template de componente. Até a próxima!

Automatizando a criação de componentes - Finalizando o pacote de componentes

Dentro da pasta "src", no nosso "component-template", vamos replicar três arquivos: Button.styles.ts, Button.tsx e index.ts. Embora possamos simplesmente copiar esses arquivos, precisamos fazer algumas alterações, especialmente no referente ao arquivo de estilos do botão.

Afinal, há particularidades de estilização do botão que não são interessantes de serem levadas para todos os componentes. Até porque pode ser que nem precisemos de estilos em um novo componente.

Quanto menos conteúdo tivermos, mais fácil será utilizar o template. Se o componente não precisar de estilização, podemos simplesmente deletar o arquivo ou aproveitá-lo de outra forma.

Finalizando pacote de componente

Dentro da pasta "component-template > src", vamos criar um novo arquivo chamado Component.styles.ts, utilizando PascalCase. Por enquanto, deixaremos o arquivo de estilos vazio.

Vamos entender em breve por que estamos nomeando os arquivos dessa forma. O "component-template" será reutilizado posteriormente para um detalhe importante na automação.

Ainda dentro de "component-template > src", vamos criar outro arquivo chamado Component.tsx. Neste arquivo, deixaremos apenas o básico.

Primeiro, importamos React de react. Em seguida, exportamos uma interface chamada ComponentProps, que ficará vazia por enquanto, pois não teremos propriedades para este componente de template.

Por fim, exportaremos uma const chamada Component, tipando-a como React.FC (Functional Component), que receberá ComponentProps. Dentro da arrow function, não haverá nenhuma prop no momento. No corpo da função, passaremos apenas uma div vazia para não ter nenhum conteúdo em tela.

Component.tsx

import React from 'react';

export interface ComponentProps {}

export const Component: React.FC<ComponentProps> = () => {
    return <div />;
};

Se houver algum erro no .tsx, pode ser devido à falta de dependências instaladas. Para resolver isso, podemos abrir o terminal e rodar pnpm install na raiz do projeto, as dependências serão instaladas, resolvendo o problema de escopo do React.

pnpm install

No entanto, isso serve apenas para remover o erro da tela. A pasta "node_modules" não terá serventia, já que não exibiremos este componente em tela. Dessa forma, criamos a estrutura de como os componentes serão.

No arquivo index.ts do botão, podemos reutilizar o export do Button e o export type do ButtonProps. Por isso, vamos copiar o index.ts do botão e colá-lo em "component-template > src". Basta alterar "Button" para "Component" nas linhas 1 e 2.

index.ts:

export { Component } from './Component';
export type { ComponentProps } from './Component';

Próximos passos

Com o template pronto, para criar um novo componente, bastaria copiar toda a pasta do "component-template", renomeá-la e substituir "component" pelo nome do novo componente. Isso poupará muito trabalho no desenvolvimento.

Na próxima aula, criaremos um script em JavaScript para executar com o Node, passando uma flag com o nome do novo componente. Assim, automatizaremos ainda mais a criação de componentes, aproveitando este template que acabamos de construir.

Nosso design system está ficando excelente. Te espero na próxima aula para desenvolver esse script.

Sobre o curso React: publicando pacotes no npm com versionamento semântico

O curso React: publicando pacotes no npm com versionamento semântico possui 131 minutos de vídeos, em um total de 46 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas