Uma experiência com Node, TypeScript, TS-Node e ESM que funciona

Desenvolvedores de Node.js descrevem atrito significativo ao combinar TypeScript, `ts-node` e módulos ECMAScript, especialmente quando os projetos envolvem monorepos, frameworks de teste como Jest e árvores de dependência complexas. Muitos argumentam que configurações padronizadas que “simplesmente funcionam” escondem complexidade importante e, em vez disso, defendem ferramentas mais simples como `tsx`, Vitest ou até runtimes alternativos como Deno e Bun, que buscam tornar o suporte a TypeScript e ESM mais transparente. Outros discordam, dizendo que a stack pode ser tornada confiável com a configuração certa, mas reconhecem que a fraca interoperabilidade, padrões em mudança e documentação fraca sobre resolução de módulos tornaram o ecossistema atual incomumente frágil.

Sentimento geral sobre Node + TypeScript + ESM

  • Muitos comentadores dizem que a combinação Node + TypeScript + ts-node + ESM é confusa, frágil e cheia de casos extremos.
  • Outros relatam que “simplesmente funciona” para eles com configuração mínima e não entendem a dificuldade.
  • Vários destacam que a dor costuma aparecer quando você adiciona vários pacotes, imports de subcaminho, executores de teste ou monorepos, não em projetos de brinquedo.

ts-node vs tsx e outros executores de TS

  • Forte apoio ao tsx como substituto direto de ts-node: mais rápido, melhor tratamento de ESM, padrões mais simples.
  • Alguns já tiveram problemas com tsx (por exemplo, Playwright, cobertura), mas relatam que os lançamentos recentes v4 corrigem muitos deles.
  • Alternativas mencionadas: esno (agora essencialmente um alias de tsx), tsm, node-dev, esyes.
  • Alguns evitam completamente transpilers em tempo de execução, preferindo tsc --build --watch e depois executar o JS compilado.

Testes, ferramentas e monorepos

  • Jest + TypeScript + ESM é repetidamente citado como doloroso; Vitest é frequentemente recomendado como uma alternativa mais suave.
  • O executor de testes integrado do Node é visto como promissor, mas a integração com loaders de TS e outras ferramentas ainda é irregular.
  • Monorepos com TypeScript, ESLint, Jest e mistura de ESM/CJS são descritos como “vodu” e frágeis; alguns compartilham modelos que funcionam para eles.

Configuração vs entendimento

  • Debate entre “apenas copie estes arquivos de configuração” e aprender o que cada opção faz.
  • Alguns argumentam que exemplos funcionando são o melhor ponto de partida; outros dizem que isso gera configurações de “cargo cult” que quebram em upgrades.
  • Reclamações de que o ecossistema TS/Node carece de bons documentos de “explicação” sobre como a resolução de módulos e as opções do tsconfig interagem, especialmente com ESM.

Design de ESM e atrito no ecossistema

  • Muitos culpam a implementação de ESM do Node pelas fraturas no ecossistema (incompatibilidade CJS/ESM, type: module, perda de __dirname, problemas com exports de subcaminho).
  • Outros argumentam que TypeScript e ferramentas como Jest demoraram para dar suporte a ESM, apesar de anos de aviso.
  • Alguns criticam fortemente o próprio design do ESM, alegando que CommonJS era mais simples e “bom o suficiente”; outros respondem que o ESM declarativo permite melhor otimização e módulos nativos do navegador.

Alternativas: Deno e Bun

  • Deno é elogiado por TypeScript que “simplesmente funciona”, ferramentas integradas e segurança, mas a compatibilidade com o ecossistema (especialmente npm) e algumas peculiaridades ainda permanecem.
  • Bun é visto como algo que magicamente suaviza os problemas de ESM/CJS e oferece ótima DX, mas também como algo muito novo e ainda cheio de bugs; muitos são cautelosos em usá-lo em produção ainda.