Sitemap

Deno 🦕

6 min readJul 26, 2020

--

A secure runtime for JavaScript and TypeScript.

Deno é um runtime simples, moderno e seguro para JavaScript e TypeScript que usa o motor V8 da Google e foi construído em Rust. Ele não é uma atualização e nem um fork do Node.js, foi criado do zero!

Criado por Ryan Dahl o mesmo criador do Node.js, todo o core do Deno foi escrito em Rust, diferente do Node.js que utiliza o C++.

Onde tudo começou

Em Jun/2018 Ryan Dahl realizou uma conferência na JSConf EU com o título 10 Things I Regret About Node.js (10 coisas que eu me arrependo do Node.js) apontando na verdade 7 coisas das quais ele se arrependia no Node.js, e foi onde ele apresentou o Deno.

10 Things I Regret About Node.js

1. Promises
Ele acrescentou promises ao Node.js em junho de 2009, mas as removeu em fevereiro de 2010 em favor de callbacks (que é a forma como conhecemos Node.js no início) e ele se arrepende disso. Hoje, muitas APIs assíncronas do Node.js estão envelhecendo muito mal devido a isso.

Depois do lançamento do ES6 (ECMAScript 2015) a plataforma implementou nativamente a funcionalidade de promises que já estava implementada no V8 desde algum tempo antes.

O Deno além claro de suportar promises, já é Top Level Await ou seja, ele permite que os desenvolvedores usem await sem a necessidade do async.

Press enter or click to view image in full size
Imagem ilustrando exemplo de código com Top Level Await

2. Segurança
No Node.js é possível acessar todas as chamadas do sistema, como gravar no disco e acessar a rede. E não deveria ser assim, por exemplo, para que meu linter deve ter acesso a minha rede se eu só quero que ele valide as regras no meu código?!

O Deno é seguro por default, portanto, a menos que você o habilite especificamente, um módulo Deno não tem acesso a arquivos, redes ou ambientes. O acesso a áreas ou funções sensíveis à segurança requer o uso de permissões concedidas a um processo Deno na linha de comando através de flags.

# Permitir acesso à rede
--allow-net
# Permite acesso de gravação ao sistema de arquivos
--allow-write

3. O sistema de compilação GYP
Os compiladores são muito complexos e muito importantes, no Node.js Ryan optou pelo GYP (Generate Your Projects) por a V8 (via Chrome) também utilizá-lo. Mais tarde o Chrome abandonou o GYP pelo GN, deixando o Node.js como único usuário do GYP.

No Node.js o GYP é utilizado para desenvolvimento de módulos nativos em C ou C++ que serão vinculados ao Node.js para que possam ser acessados ​​com require, como qualquer outro módulo JavaScript. Ryan também cita que no GYP existem camadas sobre camadas de complexidade desnecessárias.

Deno procura resolver isso usando uma mistura do GN e o cargo, o compilador do Rust. Isso fornece melhor desempenho e APIs mais amigáveis ​​para compilar módulos nativos.

4. package.json
Ryan não gosta do fato de que você precisa definir suas dependências em 2 locais, no package.json e também dentro do seu código quando você utiliza um require/import para importar o módulo.

Outro ponto que ele cita é que o package.json também contém várias outras informações, como o nome, descrição, licença e o repositório do seu projeto. Dahl chama isso de “ruído” e acredita ser desnecessário.

O Deno permite importar módulos diretamente de URLs, simplificando drasticamente todo o conceito de exigir módulos externos em seus scripts e aplicativos.

Press enter or click to view image in full size
Imagem ilustrando exemplo de um import no Deno

Particularmente acho muito ruim ter que colocar uma URL toda vez que queremos importar um módulo e não só isso, como a versão do módulo também fica na URL de importação podemos ter que sair procurando todos os lugares que a importam para poder atualizar sua versão, para esse problema o Deno tem suporte a import maps.

Press enter or click to view image in full size
Imagem ilustrando exemplo de um import map no Deno

Também podemos utilizar outra abordagem que seria de criar um arquivo (por exemplo deps.ts) que exporta todas as dependências do nosso projeto.

Press enter or click to view image in full size
Imagem ilustrando exemplo de um arquivo deps.ts exportando todas as dependências no Deno

5. node_modules
O principal problema aqui são as dependências duplicadas em cada projeto deixando a famosa pasta node_modules muito pesada. Esse conceito diverge muito da maneira como as dependências funcionam no navegador. Ryan cita que algo como uma variável de ambiente (por exemplo $NODE_PATH) resolveria e que ele se arrepende muito disso.

Press enter or click to view image in full size
Os objetos mais pesados ​​do universo

Quando você precisa de um módulo externo no Deno, ele é baixado e suas dependências são armazenadas em um diretório de cache compartilhado para todas as aplicações Deno locais, só realizando o download novamente se na execução for utilizado a flag reload.

Get Rodrigo Cichetto Monteiro’s stories in your inbox

Join Medium for free to get updates from this writer.

Adeus node_modules :D

6. require(“module”) sem extensão (.js, .ts…)
Você poder importar arquivos sem a extensão cria a necessidade de consultar o sistema de arquivos e verificar o que você realmente quis dizer quando o carregador de módulos do Node.js está resolvendo seus módulos.

Ryan argumenta que isso é menos explícito e se desvia da maneira como é feita no navegador:

<script src="example.js" type="text/javascript"></script>

O Deno não possui resolução de módulo, ele precisa da extensão .js ou .ts nas importações dos módulos.

Press enter or click to view image in full size

7. index.js
Se você importa um módulo, geralmente o index.js é usado como um arquivo de “entrada” para esse módulo ou uma aplicação. Semelhante como o index.html é resolvido por padrão na web. Dahl lamenta isso porque não é explícito, e complicou o sistema de carregamento de módulos do Node.js, introduzindo uma etapa para verificar a existência do index.js.

Já citei no item acima que o Deno não possui resolução de módulos, ele precisa da extensão .js ou .ts bem como o nome do arquivo nas importações dos módulos.

Suporte nativo ao TypeScript

“absolutely beautiful”. — Ryan Dahl

O Deno interpreta TypeScript sem que você precise instalar e nem configurar nada, também conhecido como First Class Support, não é necessário um compilador a parte para o TypeScript, isso já é feito de forma automática pelo runtime e só é recompilado quando o código é alterado.

Atualmente o Deno utiliza compilador da Microsoft mas a ideia é reescrever um compilador em Rust para obter mais performance.

Primeiros passos

Agora que apresentei o Deno e as motivações de Ryan Dahl, vou passar um rápido passo-a-passo para que você consiga executar seu primeiro código utilizando o Deno.

Primeiro precisamos instalar o Deno, para isso você pode seguir as instruções do site oficial ou se você usa o pinguim como sistema operacional é só executar o seguinte comando:

$ curl -fsSL https://deno.land/x/install/install.sh | sh

Tente rodar o script de bem vindo executando:

$ deno run https://deno.land/std/examples/welcome.ts

Afim de estudar um pouco a mais do Deno, também criei um projeto de uma API simples que retorna todos Pokémon da primeira geração!

Você consegue executar através do comando:

$ deno run --allow-read --allow-net https://raw.githubusercontent.com/rodrigocichetto/poke-deno/master/app.ts

Então bastar fazer uma requisição GET para o endpoint /api/poke-deno que ele retornará uma lista com todos os Pokémon na seguinte estrutura:

[
{
"name": "bulbasaur",
"url": "https://pokeapi.co/api/v2/pokemon/1/",
"pokedex": 1,
"image": "https://pokeres.bastionbot.org/images/pokemon/1.png"
},
...
]

Referências

--

--

Rodrigo Cichetto Monteiro
Rodrigo Cichetto Monteiro

Written by Rodrigo Cichetto Monteiro

Software Engineer na Arquivei. Amante do mundo do design e apaixonado pelas melhores tecnologias de desenvolvimento.