Publicando uma biblioteca TypeScript no npm
1. Preparação do Projeto
A estrutura de diretórios é fundamental para manter a organização e facilitar a manutenção. Recomenda-se a seguinte estrutura:
minha-biblioteca/
├── src/
│ └── index.ts
├── dist/
├── tests/
│ └── index.test.ts
├── package.json
├── tsconfig.json
├── .gitignore
└── README.md
O package.json deve conter as configurações essenciais:
{
"name": "@seu-usuario/minha-biblioteca",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"scripts": {
"build": "tsc",
"test": "jest",
"prepublishOnly": "npm test && npm run build"
}
}
O .gitignore para projetos TypeScript deve incluir:
node_modules/
dist/
*.tsbuildinfo
coverage/
.env
2. Configuração do TypeScript Compiler
O tsconfig.json é o coração da configuração. Para bibliotecas, recomenda-se:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
},
"include": ["src"],
"exclude": ["node_modules", "dist", "tests"]
}
Para suporte dual (CommonJS e ESM), é necessário configurar dois arquivos de saída:
// tsconfig.cjs.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "./dist/cjs"
}
}
// tsconfig.esm.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "esnext",
"outDir": "./dist/esm"
}
}
3. Empacotamento e Build
Os scripts de build devem automatizar o processo completo:
{
"scripts": {
"clean": "rm -rf dist",
"build:cjs": "tsc -p tsconfig.cjs.json",
"build:esm": "tsc -p tsconfig.esm.json",
"build": "npm run clean && npm run build:cjs && npm run build:esm",
"prepublishOnly": "npm run build && npm test"
}
}
Exemplo de código fonte para a biblioteca:
// src/index.ts
export interface SaudacaoOptions {
nome?: string;
idioma?: 'pt' | 'en' | 'es';
}
export function saudacao(options: SaudacaoOptions = {}): string {
const { nome = 'Mundo', idioma = 'pt' } = options;
const saudacoes = {
pt: `Olá, ${nome}!`,
en: `Hello, ${nome}!`,
es: `¡Hola, ${nome}!`
};
return saudacoes[idioma];
}
export function somar(a: number, b: number): number {
return a + b;
}
4. Gerenciamento de Dependências e Peer Dependencies
É crucial entender a diferença entre os tipos de dependências:
{
"dependencies": {
"lodash": "^4.17.21" // Dependência de runtime
},
"devDependencies": {
"typescript": "^5.0.0",
"jest": "^29.0.0",
"@types/jest": "^29.0.0",
"@types/lodash": "^4.14.0"
},
"peerDependencies": {
"react": "^18.0.0" // Para bibliotecas React
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
}
}
Boas práticas:
- dependencies: Apenas o necessário para a biblioteca funcionar
- devDependencies: Ferramentas de desenvolvimento e tipos
- peerDependencies: Bibliotecas que o usuário já deve ter instalado
5. Publicação no npm
Processo completo de publicação:
# Login no npm
npm login
# Versionamento semântico
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.0
# Publicação
npm publish --access public
Para pacotes scoped (privados por padrão):
{
"name": "@seu-usuario/minha-biblioteca",
"publishConfig": {
"access": "public"
}
}
Publicação com tags:
npm publish --tag beta
npm dist-tag add @seu-usuario/minha-biblioteca@1.0.0 latest
6. Testes e Qualidade Antes da Publicação
Configuração completa de testes com Jest:
// jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/tests'],
testMatch: ['**/*.test.ts'],
collectCoverage: true,
coverageDirectory: 'coverage',
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
}
};
Exemplo de teste:
// tests/index.test.ts
import { saudacao, somar } from '../src';
describe('saudacao', () => {
it('deve retornar saudação padrão', () => {
expect(saudacao()).toBe('Olá, Mundo!');
});
it('deve retornar saudação personalizada', () => {
expect(saudacao({ nome: 'João' })).toBe('Olá, João!');
});
it('deve suportar diferentes idiomas', () => {
expect(saudacao({ nome: 'John', idioma: 'en' })).toBe('Hello, John!');
});
});
describe('somar', () => {
it('deve somar dois números corretamente', () => {
expect(somar(2, 3)).toBe(5);
});
});
Configuração de linting:
// .eslintrc.json
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/no-explicit-any": "error"
}
}
7. Documentação e Exemplos
Geração automática de documentação com TypeDoc:
npm install --save-dev typedoc
// typedoc.json
{
"entryPoints": ["src/index.ts"],
"out": "docs",
"excludePrivate": true,
"excludeProtected": true,
"theme": "default"
}
Exemplo de README completo:
# Minha Biblioteca
[](https://badge.fury.io/js/@seu-usuario/minha-biblioteca)
[](https://travis-ci.org/seu-usuario/minha-biblioteca)
[](https://coveralls.io/github/seu-usuario/minha-biblioteca)
## Instalação
```bash
npm install @seu-usuario/minha-biblioteca
Uso
import { saudacao, somar } from '@seu-usuario/minha-biblioteca';
// Saudação personalizada
console.log(saudacao({ nome: 'Maria', idioma: 'pt' }));
// Output: Olá, Maria!
// Operações matemáticas
console.log(somar(10, 20));
// Output: 30
API
saudacao(options?)
Retorna uma saudação personalizada.
Parâmetros:
- options.nome (string, opcional): Nome da pessoa (padrão: 'Mundo')
- options.idioma ('pt' | 'en' | 'es', opcional): Idioma da saudação (padrão: 'pt')
Retorno: string
somar(a, b)
Soma dois números.
Parâmetros:
- a (number): Primeiro número
- b (number): Segundo número
Retorno: number
```
Referências
- Documentação oficial do TypeScript - tsconfig.json — Guia completo de todas as opções de configuração do compilador TypeScript
- npm Docs - Publishing packages — Documentação oficial para publicação de pacotes no npm registry
- TypeDoc - Documentation generator for TypeScript — Ferramenta oficial para geração automática de documentação a partir de código TypeScript
- Jest Documentation - Getting Started with TypeScript — Guia oficial para configurar testes unitários com Jest e TypeScript
- npm Docs - package.json — Documentação completa sobre todas as propriedades do package.json
- ESLint - TypeScript Configuration — Guia oficial para configurar ESLint com TypeScript
- Semantic Versioning Specification — Especificação oficial do versionamento semântico (SemVer)