Ferramentas Open Source que Automatizam o Trabalho Chato do Seu Dia a Dia em JavaScript
O problema não é falta de ferramenta, é excesso de trabalho manual disfarçado de processo
Toda equipe que trabalha com JavaScript acumula tarefas manuais que ninguém automatiza porque "leva cinco minutos". Atualizar changelog antes do release. Verificar se alguma dependência tem CVE. Rodar lint só quando alguém lembra. Criar tag de versão copiando o número do package.json. Cada uma dessas tarefas leva cinco minutos. Multiplicadas por semana, por repositório, por pessoa, consomem horas que poderiam ir para código que importa.
Este post cobre oito automações concretas usando ferramentas open source, com scripts copy-paste ready, comparações entre alternativas e os anti-patterns que transformam automação em mais uma fonte de atrito. O foco é JavaScript/TypeScript, mas vários workflows se aplicam a qualquer stack que rode em CI.
Automação 1: Lint e formatação no commit, não no PR
Rodar lint na CI é o mínimo. Rodar lint antes do commit evita que o PR sequer chegue com ruído. A combinação lint-staged + husky resolve isso com zero overhead para quem já tem ESLint e Prettier configurados.
# Instalação com versões explícitas para reprodutibilidade
npm install --save-dev husky@9 lint-staged@15
npx husky init
// package.json — seção lint-staged
// Roda Prettier apenas nos arquivos staged, não no projeto inteiro.
// Isso mantém o hook rápido mesmo em monorepos com milhares de arquivos.
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"eslint --fix --max-warnings=0",
"prettier --write"
],
"*.{json,md,yaml}": [
"prettier --write"
]
}
}
# .husky/pre-commit
# O hook chama lint-staged, que filtra só arquivos no staging area.
npx lint-staged
O --max-warnings=0 é intencional: warnings que ninguém corrige são ruído que treina o time a ignorar alertas. Se o warning não importa, desabilite a regra. Se importa, trate como erro.
Para quem quer entender como closures e escopo afetam regras de lint mais avançadas, vale ler Coerção, Closures e Protótipos: As Mecânicas do JavaScript que Você Usa Sem Entender.
Automação 2: Changelog e versionamento com Changesets
Gerar changelog manualmente é trabalho que escala mal. Duas abordagens dominam o ecossistema:
| Critério | Changesets | semantic-release |
|---|---|---|
| Modelo de commit | Arquivo .changeset por PR | Conventional Commits obrigatório |
| Controle do dev | Escolhe tipo de bump e descrição por PR | Automático baseado no prefixo do commit |
| Monorepo | Suporte nativo com workspace protocol | Requer plugins extras |
| Curva de aprendizado | Baixa (comando interativo) | Média (configuração de plugins) |
| Quando usar | Times que querem revisar o changelog antes do publish | Projetos solo ou libs com release contínuo |
Para a maioria dos projetos com mais de um contribuidor, Changesets oferece mais controle sem sacrificar automação.
npm install --save-dev @changesets/cli@2
npx changeset init
// scripts/validate-changeset.ts
// Roda na CI para garantir que todo PR que toca código inclua um changeset.
// Sem isso, PRs passam sem entrada no changelog e o histórico fica incompleto.
import { execSync } from "node:child_process";
import { readdirSync } from "node:fs";
import { join } from "node:path";
const changesetDir = join(process.cwd(), ".changeset");
function hasNewChangeset(): boolean {
const mainBranch = "origin/main";
const diffOutput = execSync(
`git diff --name-only ${mainBranch}...HEAD`,
{ encoding: "utf-8" }
);
const changedFiles = diffOutput.split("\n").filter(Boolean);
return changedFiles.some(
(file) => file.startsWith(".changeset/") && file.endsWith(".md")
);
}
function hasCodeChanges(): boolean {
const mainBranch = "origin/main";
const diffOutput = execSync(
`git diff --name-only ${mainBranch}...HEAD`,
{ encoding: "utf-8" }
);
const codeExtensions = [".ts", ".t
---
Leia o artigo completo em [https://www.vivodecodigo.com.br/backend/ferramentas-opensource-produtividade-automacao-javascript](https://www.vivodecodigo.com.br/backend/ferramentas-opensource-produtividade-automacao-javascript)