Um formulário aberto na internet acaba por receber a visita de um robô. Sem limite nenhum, uma tarde chega para encher a base de dados — e o custo de a limpar é sempre maior do que o de a proteger. 1. Janela fixa: simples, com um defeito const contagens = new Map(); function dentroDoLimite(chave, ma…
Ler o artigo→Há duas formas de uma página ser rápida: servir depressa, ou não ter de servir de todo. A segunda é sempre melhor, e mora num cabeçalho. 1. Cache-Control, em três casos # Ficheiro com hash no nome (app.9f3c2a.js): nunca muda de conteúdo Cache-Control: public, max-age=31536000, immutable # Uma página…
Ler o artigo→O truque de copiar um objeto com JSON.parse(JSON.stringify(objeto)) anda em código de produção há anos. Funciona até ao dia em que o objeto tem uma data, um Map , um undefined ou uma referência a si próprio — e aí falha em silêncio ou rebenta. O structuredClone é a função nativa que faz esse trabalh…
Ler o artigo→A aplicação corre em localhost:3000 , o Nginx trata do domínio e do certificado, e tudo parece bem — até ao dia em que os endereços que ela gera saem com http://0.0.0.0:3000 , e todos os visitantes ficam com o mesmo IP no registo. O motivo é sempre o mesmo: a aplicação vê o proxy, não vê quem visita…
Ler o artigo→Durante anos, escrever o primeiro teste de um projeto Node começava por escolher entre o Jest, o Mocha, o Vitest e mais três — e por instalar duzentos pacotes para correr uma asserção. Desde a versão 20, o Node traz um executor de testes embutido . Para projetos pequenos e para bibliotecas, muitas v…
Ler o artigo→Funcionava no mês passado, está partido hoje, e pelo meio há duzentos commits. A forma manual de encontrar o culpado é ir recuando e experimentando — e são duzentas tentativas no pior caso. O git bisect faz uma busca binária pelo histórico: com duzentos commits, encontra-o em oito tentativas. 1. À m…
Ler o artigo→Durante vinte e cinco anos, o sort() e o reverse() alteraram o array em que eram chamados. É a origem de uma classe inteira de bugs: uma função recebe uma lista, ordena-a para mostrar, e devolve-a alterada a quem a emprestou. O ECMAScript 2023 acrescentou quatro métodos que fazem o mesmo sem tocar n…
Ler o artigo→Toda a gente sabe que deve fazer cópias de segurança. O que se descobre tarde é que uma cópia por restaurar não é uma cópia — é uma esperança . 1. A regra 3-2-1 3 cópias dos dados — a original e duas. 2 suportes diferentes — não as duas no mesmo disco, nem as duas na mesma máquina. 1 fora do sítio —…
Ler o artigo→Um ecrã que carrega dados tem três estados possíveis, e quase toda a gente os escreve assim: type Estado = { aCarregar: boolean; dados?: Artigo[]; erro?: string; }; O problema deste tipo é que ele permite coisas impossíveis: aCarregar: true com dados e com erro ao mesmo tempo. Nada no compilador imp…
Ler o artigo→É o problema de desempenho mais comum em qualquer aplicação com base de dados, e o mais difícil de ver a olho nu — porque o código que o causa parece perfeitamente razoável. const artigos = await db.artigos.findMany({ take: 20 }); for (const artigo of artigos) { artigo.autor = await db.autores.findU…
Ler o artigo→O Object.groupBy entrou no JavaScript com o ECMAScript 2024 e resolve uma coisa que toda a gente já escreveu à mão pelo menos uma vez: separar uma lista em grupos, segundo um critério qualquer. O que muda Deixa de ser preciso um reduce com um acumulador e a verificação do costume para o caso de a ch…
Ler o artigo→Acessibilidade tem fama de ser um assunto enorme, com uma norma de centenas de páginas. É verdade — e também é verdade que uma mão-cheia de hábitos apanha a maior parte dos problemas reais de um site normal. 1. HTML com significado É o mais importante, e o mais barato: um <button> já é focável, já r…
Ler o artigo→Uma imagem Docker de uma aplicação Node feita à pressa leva lá dentro o compilador de TypeScript, as ferramentas de teste, o node_modules de desenvolvimento inteiro e o código-fonte. Nada disso corre em produção — mas tudo isso é descarregado a cada deploy, e tudo isso é superfície de ataque. O mult…
Ler o artigo→Uma consulta que respondia em 3 ms com mil linhas passa a demorar 900 ms com duzentas mil. O código não mudou. O que mudou foi a base ter passado do tamanho em que ler tudo era aceitável para o tamanho em que não é. 1. Perguntar ao Postgres o que ele faz EXPLAIN ANALYZE SELECT id, title FROM posts W…
Ler o artigo→Há uma escolha que o TypeScript obrigava a fazer desde sempre: ou se anota o tipo de uma constante — e perde-se tudo o que ela tem de específico — ou não se anota nada, e ninguém verifica se está certa. O satisfies , que chegou no TypeScript 4.9 , acaba com a escolha: verifica o valor contra um tipo…
Ler o artigo→Este código funciona em desenvolvimento e cai em produção: import { readFile } from 'node:fs/promises'; const conteudo = await readFile('registos.csv', 'utf8'); const linhas = conteudo.split('\n'); Com um ficheiro de teste de 2 MB, é instantâneo. Com o ficheiro real de 3 GB, o processo tenta carrega…
Ler o artigo→Quem vem do Webpack e experimenta o Vite pela primeira vez faz sempre a mesma pergunta: como é que o servidor de desenvolvimento está pronto em menos de um segundo, num projeto onde o outro demorava trinta? A resposta não é "é mais rápido a fazer o mesmo". É que faz outra coisa . 1. O Webpack constr…
Ler o artigo→Uma transferência bancária são duas operações: tirar de uma conta e pôr noutra. Se o processo morre entre as duas, o dinheiro desapareceu. É o exemplo de sempre, e explica para que serve uma transação. BEGIN; UPDATE contas SET saldo = saldo - 100 WHERE id = 1; UPDATE contas SET saldo = saldo + 100 W…
Ler o artigo→Está em todas as linhas de dependências de todos os projetos, e é frequentemente lido como decoração. Não é: é um contrato sobre o que pode entrar no seu projeto sem ninguém dar por isso. 1. Os três números 3 . 4 . 2 │ │ └── PATCH: correções, sem mudar comportamento │ └────── MINOR: funcionalidades …
Ler o artigo→Carregar imagens só quando são precisas, animar uma secção quando ela aparece, marcar no menu o capítulo que está a ser lido: são três funcionalidades diferentes com o mesmo problema por baixo — saber o que está visível. A forma antiga era ouvir o evento scroll e medir posições. Corria dezenas de ve…
Ler o artigo→