Novidades do Deno 1.40
O Deno chegou na versão 1.40 e essa é uma das versões mais legais de todas! Primeiro, porque ela tem a adição da Temporal API que eu estou falando aqui desde 2020! E eu acho que é o primeiro runtime a implementar essa funcionalidade de fato!
Além disso, uma série de outras novidades que eu vou passar por aqui uma por uma!
Temporal API#
A temporal API é a nova forma de lidar com as datas no JavaScript, eu falei muito sobre ela neste artigo e mostrei todos os detalhes, então não vou entrar em muitos detalhes aqui, mas essencialmente, o Deno é o primeiro runtime que implementa essa API completamente.
Ela ainda está por trás de uma flag --unstable-temporal mas você já pode utilizar da mesma forma que a documentação oficial informa! Se você rodar um terminal com deno --unstable-temporal, você já pode fazer alguns testes:
console.log(Temporal.Now.instant()) // data e hora de hojeconsole.log(Temporal.Now.zonedDateTimeISO()) // equivalente ao toISOStringconst birthday = Temporal.PlainMonthDay.from("12-15");const birthdayIn2030 = birthday.toPlainDate({ year: 2030 });console.log(birthdayIn2030.toString()); // 2030-12-15Por algum motivo o método Temporal.Now.timeZoneId não foi implementado.
Import.meta.filename e dirname#
Isso aqui era algo que eu queria muito que acontecesse. Desde o advento dos ECMAScript modules, toda a forma de resolução de módulos mudou, o que significa que pegar o nome de um arquivo ou o diretório onde ele existe não são mais tão simples de buscar.
No Node, temos duas variáveis “mágicas” chamadas __dirname e __filename que retornam respectivamente o caminho do diretório e do arquivo que você está executando.
Mas com ESM não podemos usá-las porque elas não são setadas no início da aplicação, então temos que buscar a URL do módulo com import.meta.url, que retorna uma fileURL no modelo file://caminho, e ai temos que usar dirname nessa URL, mas apenas depois de converter essa URL para um caminho!
import { fileURLToPath } from 'node:url'import { dirname } from 'node:path'
const fileurl = import.meta.urlconst path = fileURLToPath(fileurl)const dir = dirname(path)const filename = path.split('/').pop()
console.log({ fileurl, path, dir, filename })/*{ fileurl: "file:///Users/lucas/repos/deno/teste.ts", path: "/Users/lucas/repos/deno/teste.ts", dir: "/Users/lucas/repos/deno", filename: "teste.ts"}*/Isso era muito chato! Especialmente se você tinha que lidar com caminhos constantemente, então duas propostas foram adicionadas para poder suportar tanto o arquivo quanto a pasta, chamadas import.meta.filename e import.meta.dirname, agora você pode substituir tudo isso por:
console.log(import.meta.dirname) // /Users/lucas/repos/denoconsole.log(import.meta.filename) // /Users/lucas/repos/deno/teste.tsDecorators#
Finalmente vamos ter suporte nativo a decorators, uma proposta que está no estágio final e deve chegar nos browsers logo mais! Depois de mais de 5 anos em espera, a nova proposta junta todas as propostas anteriores em uma só.
Um exemplo clássico que a gente pode dar é o @trace que serve para debugar qualquer função colocando um console antes e depois da execução:
function trace(fn: any, ctx: ClassMethodDecoratorContext) { return function (...args: unknown[]) { console.log("ENTERED", ctx.name); const v = fn(...args); console.log("EXITED", ctx.name); return v; };}
class App { @trace static start() { console.log("Hello World!"); }}
App.start();Imports mais simples#
Essa é outra novidade interessante. Antigamente, quando tínhamos import maps com módulos que tinham subdiretórios, tínhamos que definir dois imports diferentes:
{ "imports": { "preact": "npm:preact@10.5.13", "preact/": "npm:/preact@10.5.13/" }}Isso permitia que a gente pudesse importar tanto o top-level preact com import preact from 'preact', e também os submódulos tipo import hooks from 'preact/hooks'.
Agora a simplificação funciona para que você possa só ter um módulo no import map e consiga importar tudo da mesma raiz só com um map:
{ "imports": { "preact": "npm:preact@10.5.13" }}Embora eu não goste muito de usar import maps e prefira a abordagem de um arquivo
deps.ts
Outras mudanças#
- Uma série de APIs e comandos estão sendo depreciados, em especial o
deno.runedeno.serveHttp - Suporte ao
rejectionHandled, um evento que é disparado sempre que uma exception acontece em uma promise que já foi rejeitada (quando você tem um catch não usado) - Suporte a janelas com WebGPU
- Suporte a novas APIs nativas do Node.js
- Melhores mensagens no deno lint e deno doc