Como publicar seu primeiro package TS e automatizar com Github Actions

Introdução

Nesse artigo vou abordar a criação e publicação de um package escrito em Typescript para o NPM. A minha principal motivação é escrever algo que seja simples mas não deixe de levar em consideração fatores importantes, como versiona…


This content originally appeared on DEV Community and was authored by Thiago Moraes

Introdução

Nesse artigo vou abordar a criação e publicação de um package escrito em Typescript para o NPM. A minha principal motivação é escrever algo que seja simples mas não deixe de levar em consideração fatores importantes, como versionamento, atualização, testes e automatização. O que será abordado:

  • Criar um package em TS
  • Boas práticas de teste pre release
  • Publicar um package público no npm
  • Gerenciar atualizações
  • Noções de versionamento
  • Automatizar a publicação com github actions

Pré-requisitos

  • Criar uma conta no Github
  • Criar uma conta no NPM

Configurando o ambiente para o package

Criando o repositório

Nosso package vai se chamar math-ops e será responsável por fazer operações matemáticas básicas. Sendo assim, vamos criar um novo repositório com o nome escolhido:

Screenshot from 2021-06-13 19-07-03

Inicializando o repositório

Vamos criar um novo diretório e acessá-lo:

mkdir math-ops && cd math-ops

Em seguida vamos configurar o repostório git e enviar o primeiro commit.

echo "# math-ops" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:thiagomr/math-ops.git
git push -u origin main

Configurando o package

Inicializando as configurações do NPM

npm init

Como resultado deste comando teremos a seguinte saída:

//package.json

{
  "name": "@thiagomr/math-ops",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/thiagomr/math-ops.git"
  },
  "author": "Thiago Moraes",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/thiagomr/math-ops/issues"
  },
  "homepage": "https://github.com/thiagomr/math-ops#readme"
}

Nessa etapa é importante notar que definimos o nome do package (você deve mudar de acordo com o seu nome de usuário ou nome do package que você desejar), que será utilizado para instalar o mesmo. Também foi definida a versão 0.1.0, seguindo os padrões de Semantic Version. Este é um padrão que nos permite incrementar a versão de acordo com o tipo da atualização. Você pode se aprofundar sobre o assunto aqui. Vamos considerar que estamos criando uma release não oficial, ou seja, anterior à versão 1.0.0. É interessante também perceber que como ja temos o git configurado nesse diretório, o npm automaticamente sugere o preenchimento das configurações de url e homepage do mesmo.

Instalando as dependências

Em seguida vamos instalar as dependências que utilizaremos no projeto, que são basicamente o Typescript e o Jest (e alguns auxiliares para ambos):

npm install typescript jest @types/jest ts-jest --save -D

Vamos adicionar o arquivo tsconfig.json com as configurações que usaremos para compilar o projeto:

//tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./lib",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "declaration": true
  },
  "include": [
    "src"
  ],
  "exclude": [
    "**/*.spec.ts"
  ]
}

Em seguida, iremos adicionar alguns scripts para fazer o build do projeto e uma configuração bem simples para o Jest, ferramenta que usaremos para criar testes para as funcionalidades. Nosso arquivo com as alterações ficará da seguinte forma:

//package.json

{
  "name": "@thiagomr/math-ops",
  "version": "0.1.0",
  "description": "A package to make basic math operations",
  "main": "lib/index.js",
  "types": "lib/index.d.ts",
  "scripts": {
    "clean": "rimraf lib",
    "build": "npm run clean && tsc",
    "test": "jest",
    "prepublish": "npm run test && npm run build"
  },
  "author": "Thiago Moraes",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/thiagomr/math-ops.git"
  },
  "bugs": {
    "url": "https://github.com/thiagomr/math-ops/issues"
  },
  "homepage": "https://github.com/thiagomr/math-ops#readme",
  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "coveragePathIgnorePatterns": [
      "/node_modules/",
      "lib"
    ]
  },
  "files": [
    "lib/**/*"
  ],
  "devDependencies": {
    "@types/jest": "^26.0.23",
    "jest": "^27.0.4",
    "ts-jest": "^27.0.3",
    "typescript": "^4.3.2"
  }
}


Algumas explicações mais detalhadas:

  • "main": "lib/index.js", Será o arquivo que vai expor a API pública do nosso pacote.
  • "types": "lib/index.d.ts", Indica a declaração de tipos do TS, gerado automáticamente de acordo com as nossas configurações de compilação feitas anteriormente.
  • "jest": {...} Configuração para que o Jest funcione usando TS e indicação de arquivos a serem ignorados.
  • "files": {...} Arquivos que desejamos incluir no nosso pacote.
  • "prepublish" Executa um script antes de publicar o package. Neste caso vamos rodar os testes unitários.
  • "build" Faz a compilação do projeto. De maneira bem resumida, seria o processo de typechecking e transpilação do código TS para JS.

Para finalizar essa etapa, vamos criar um arquivo .gitignore:

//.gitignore

node_modules
lib

E então vamos enviar toda a configuração para o repositório:

git add .
git commit -m "add dependecies"
git push

Criando a primeira funcionalidade

Agora vamos adicionar o arquivo com a primeira funcionalidade, que irá retornar a soma entre dois números:

// src/sum.ts

const sum = (firstNumber: number, secondNumber: number): number => {
    return firstNumber + secondNumber;
}

export {
    sum
}

Vamos criar também um arquivo de entrada para exportar a API pública do nosso package:

// src/index.ts

export * from './sum';

Testando o package

Vamos escrever nosso primeiro teste untário para a funcionalidade de sum:

// src/sum.spec.ts

import { sum } from './sum';

test('should return a sum of two numbers', () => {
    const result = sum(3, 2);
    expect(result).toEqual(5);
});

Rodando os testes:

npm test

Agora que já temos nosso primeiro teste unitário, vamos testar o uso real do package. Nós vamos utilizar o comando npm link. Isso fará com que o npm crie uma referência local para esse projeto, podendo ser utilizado de forma direta em outros projetos. É uma forma de testar seu package no ambiente de desenvolvimento sem precisar publicá-lo várias vezes.

O primeiro comando será executado no diretório do package e o segundo em um novo diretório para testes:

# math-ops
npm link

# testdir
npm link @thiagomr/math-ops

No diretório de testes, vamos criar um arquivo que importa e utiliza a funcionalidade sum:

// testdir/index.ts

const { sum } = require('@thiagomr/math-ops');
const result = sum(2, 3);

// sum is 5
console.log(`sum is ${result}`);

Para finalizar, vamos atualizar nosso repositório com as novas mudanças:

git add .
git commit -m "add sum feature"
git push

Publicando no NPM registry

Agora que já temos nosso pacote funcional e testado localmente, vamos para a fase de publicação. Vamos adicionar um arquivo .npmignore que vai excluir os arquivos desnecessários, enviando apenas o essencial e diminuindo o tamanho do package:

//.npmignore

src
node_modules

Iremos fazer o login no npm com a conta desejada:

npm login

Por padrão o versionamento do NPM utiliza o sistema de tags do GIT para indicar a publicação de novas versões. É importante manter o versionamento do NPM e GIT sincronizados, mas vale ressaltar que não há nenhuma regra que faça uma ligação entre as duas coisas. Existem alguns packages que facilitam o gerenciamento de ambos, mas como a intenção aqui é mostrar a funcionalidade básica e o mais pura possível, não utilizaremos nenhuma ferramenta adicional.

Vamos atualizar o repositório com a tag de versão incial e em seguida publicar no npm:

git tag v0.1.0
git push --tags
npm publish --access=public

Agora já temos nosso pacote publicado e disponível para instalação (O meu está em uma versão um pouco a frente pois fiz alguns testes para o artigo):

Screenshot from 2021-06-14 20-51-47

Adicionando novas funcionalidades

Nessa etapa vamos adicionar uma nova feature. Isso vai reforçar os conceitos aplicados, trazendo familiaridade com o processo. Vamos adicionar uma funcionalidade que retorna o resultado da multiplicação entre dois números index.ts:

// src/times.ts

const times = (firstNumber: number, secondNumber: number): number => {
    return firstNumber * secondNumber;
}

export {
    times
}
//src/index.ts

export * from './sum'
export * from './times'

Seguindo o processo anterior, vamos escrever um teste unitário para a nova funcionalidade:

//src/times.spec.ts

import { times } from './times';

test('should return the multiplication of two numbers', () => {
    const result = times(3, 3);
    expect(result).toEqual(9);
});

Vamos atualizar o repositório e publicar a nova versão:

git add .
git commit -m "add times feature"
npm version minor
git push --tags
npm publish --access=public

Agora você poderá o ver o package atualizado no NPM registry.

Automatizando a publicação com Github Actions

Agora que já vimos como fazer todo o processo manualmente, vamos automatizar a publicação utilizando Github Actions.
Vamos criar um token no NPM aqui, para que seja possível fazer a publicação através do Github.
Vamos inserir nosso token como uma variável de ambiente do GIT, acessando o repostório e em seguida selecionado as opçoes Settings > Secrets > New Repository Secret:

Screenshot from 2021-06-14 20-58-56

Em seguida vamos criar o arquivo de configuração do pipeline para que seja executado sempre que ouver uma alteração na branch main e no arquivo package.json:

# .github/workflows/publish.yml
on:
  push:
    branches: [ main ]
    paths:
      - 'package.json'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 14
      - run: npm install
      - uses: JS-DevTools/npm-publish@v1
        with:
          token: ${{ secrets.NPM_TOKEN }}

Para testar o pipeline, nós criaremos a última funcionalidade ao nosso package, capaz de subtrair dois números:

const subtract = (firstNumber: number, secondNumber: number): number => {
    return firstNumber - secondNumber;
}

export {
    subtract
}

Vamos novamente atualizar a entrada do package:

//src/index.ts

export * from './sum'
export * from './times'
export * from './subtract'

Assim como nos passos anteriores, vamos criar um teste unitário para o mesmo:

// src/subtract.spec.ts

import { subtract } from './subtract';

test('should return the subtraction of two numbers', () => {
    const result = subtract(4, 4);
    expect(result).toEqual(0);
});

Agora vamos enviar nossas alterações para o repositório e atualizar a versão do nosso package:

git add .
git commit -m "add subtract feature"
npm version minor
git push --tags

Se a nossa configuração estiver correta e tudo ocorrer bem, podemos verificar o pipeline no Github executado com sucesso e a nova versão publicada no NPM:

Screenshot from 2021-06-14 21-04-51

Screenshot from 2021-06-14 21-05-12

Agora vamos adicionar um exemplo de uso do package que também estará no README.md do repositório:

// Install
npm install @thiagomr/math-ops
import { sum } from '@thiagomr/math-ops';

//6
console.log(sum(4, 2));

Conclusão

Isso é tudo pessoal. Aqui está o link do repistório com todo o código utilizado. Espero que tenha ficado claro e que de alguma forma possa ajudar vocês a publicarem seus próprios packages. Gostaria de ouvir feedbacks, opiniões, sugestões e o que mais desejarem. Me sigam no Twitter para mais novidades. Grande abraço e até a próxima!


This content originally appeared on DEV Community and was authored by Thiago Moraes


Print Share Comment Cite Upload Translate Updates
APA

Thiago Moraes | Sciencx (2021-06-15T01:30:25+00:00) Como publicar seu primeiro package TS e automatizar com Github Actions. Retrieved from https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/

MLA
" » Como publicar seu primeiro package TS e automatizar com Github Actions." Thiago Moraes | Sciencx - Tuesday June 15, 2021, https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/
HARVARD
Thiago Moraes | Sciencx Tuesday June 15, 2021 » Como publicar seu primeiro package TS e automatizar com Github Actions., viewed ,<https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/>
VANCOUVER
Thiago Moraes | Sciencx - » Como publicar seu primeiro package TS e automatizar com Github Actions. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/
CHICAGO
" » Como publicar seu primeiro package TS e automatizar com Github Actions." Thiago Moraes | Sciencx - Accessed . https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/
IEEE
" » Como publicar seu primeiro package TS e automatizar com Github Actions." Thiago Moraes | Sciencx [Online]. Available: https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/. [Accessed: ]
rf:citation
» Como publicar seu primeiro package TS e automatizar com Github Actions | Thiago Moraes | Sciencx | https://www.scien.cx/2021/06/15/como-publicar-seu-primeiro-package-ts-e-automatizar-com-github-actions/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.