OpenWebinars

Frameworks

Qué es Deno y qué lo hace diferente

En este artículo tratamos sobre una una tecnología bastante reciente y que promete dar batalla al predominio de NodeJS en el ámbito de desarrollo backend.

Alfredo Barragán

Alfredo Barragán

Experto Full Stack con PHP y JavaScript

Lectura 8 minutos

Publicado el 3 de enero de 2022

Compartir

Qué es Deno

Deno es un runtime basado en la v8 de Chrome, desarrollado en el lenguaje de programación Rust y que compite directamente con Node.js, tanto en funcionalidades como en casos de uso.

NodeJS surgió en el año 2009, siendo una de las tecnologías más revolucionarias, imponiendo una auténtica innovación, sirviendo código JS en el lado del servidor, ofreciendo rendimientos superiores a tecnologías ya consolidadas como Python o Java. Node.js, provocó una auténtica revolución en el desarrollo web, siendo uno de los precursores de la programación asíncrona, tan extendida en la actualidad.

Por otro lado, para la comunidad desarrolladores fue una auténtica revolución, con el conocimiento de un único lenguaje de programación se podrían desarrollar aplicaciones tanto de backend como de frontend, promoviendo una menor curva de aprendizaje y una mayor eficiencia de los equipos de programación.

No obstante, la propia arquitectura de Node.js, tenía sus particularidades y problemas para adaptarse a los cambios de los estándares, y el paso del tiempo lo acentúo. Esta situación provoca qué en el año 2018, el propio creador de NodeJS, desarrolle Deno, no con el objetivo de desbancar, ni sustituir al anterior, pero si para solventar todos los parches y dificultades que habían yendo surgiendo con el paso del tiempo en node.js, y que cada vez era más complicado de solventar e implementar.

En las líneas precedentes analizaremos esta nueva tecnología y conoceremos las diferencias con node.js, y si realmente es un sustituto digno de node.js, que ha prevalecido durante años en el mundo del desarrollo backend.

Deno, al igual que Node.js, es un runtime multiplataforma basado en el motor V8 de Chrome, con la diferencia de que Deno, utiliza TypeScript como lenguaje por defecto y ha sido desarrollado en Rust. Aunque Deno sigue la misma arquitectura que Node.js, es decir, event driven, asincronía, etc, es un proyecto totalmente nuevo.

Mientras que Node fue escrito en C++, Deno está escrito en Rust y hace uso de librerías como Tokio, utilizada para el Event Loop de Deno. Este cambio de lenguaje aporta una serie de pistas que indican qué esperar de Deno, y es que por las propias características de Rust, lo hacen un lenguaje un lenguaje muy seguro y con un rendimiento excepcional.

Por qué surge Deno

Deno surge para suplir una serie de defectos que en NodeJS, se habían acentuado con el paso del tiempo y el avance de las tecnologías, si tuviéramos que dar una serie de causas, serían las siguientes:

  • Adaptación a los cambios del lenguaje compleja
    Node.js popularizó el famoso término callback hell, Callbacks anidados que provocan que el código se vuelva difícil de leer y debuggear. Un ejemplo de esta dificultad ha sido la implementación de los módulos de ECMAScript, con un periplo bastante tortuoso e incompleto en muchas ocasiones, de hecho, muchas librerías aún siguen usando callbacks, que provocan un rendimiento muy bajo a la par que un mantenimiento muy elevado.

  • Gestión de las dependencias
    NPM es un repositorio centralizado, propiedad de una empresa privada y aunque se han introducido muchas mejoras con los años, la carpeta node_modules sigue siendo un gran fuente de problemas relacionados con la seguridad y estabilidad de las aplicaciones. Cabe destacar como ejemplo, el famoso paquete que fue eliminado del registro causando la rotura de las builds de medio mundo, incluyendo Node, Babel, React, etc.

  • Módulos
    El sistema de módulos de Node.js basado en require fue una solución muy útil, en aquel momento, porque sencillamente no existía otra alternativa, pero es una solución que hoy día, con los módulos de ECMASCript no tiene mucho sentido. Con Deno este aspecto ha sido solucionado y adaptado a los estándares internacionales.

  • Isomorfismo
    Node.js es un runtime multiplataforma, pero la realidad es que nunca ha llegado a serlo del todo ya que en node.js no existen los objetos globales como Window y su propia API no es soportada por los navegadores.

Deno vs Node.js

Aunque a priori, puede parecer que Deno es una copia de Node.js, esta afirmación está muy alejada de la realidad. Las principales diferencias entre las dos plataformas son:

  • Seguridad:
    Si se pudiera definir a Deno con un único término sería el de seguridad. Con Node, la ejecución de un determinado programa, éste adquiere todos los permisos, por lo que podría hacer cualquier cosa en tu equipo. En la práctica un programa escrito en Node, podría borrar todos los archivos de tu ordenador, con lo que un software malicioso podría causar problemas.
    Con Deno en cambio el desarrollador es capaz de otorgar solamente los permisos que sean absolutamente necesarios, como conectar por http, escribir solamente en unas carpetas determinadas, etc, con lo cual se tiene mucho más control sobre los permisos.

  • No usa npm
    Deno no tiene un gestor de dependencias como tiene Node.js en npm. Todas las dependencias las instala a través de la URL donde está la dependencia en sí, por lo que es capaz de funcionar sin depender de un repositorio centralizado.
    Deno usa un gestor interno para manejar los paquetes internos, que funciona de forma transparente al desarrollador. Este gestor se encarga de optimizar el funcionamiento de las dependencias, descargar o cachear sus archivos, gestionar las versiones, etc. Aportando sencillez y agilidad para los desarrolladores.

  • Usa los módulos ES6
    En lugar de CommonJS como usa node.js, Deno utiliza los módulos ES6, esto lo hace mucho más cercano al estándar de Javascript y permite que el desarrollo de Deno sea más similar todavía a las técnicas de desarrollo que se tienen en los navegadores.

  • Promesas en vez de Callbacks
    Deno para gestionar los procesos asíncronos, usa promesas en lugar de funciones callback. Esto se traduce en un código más legible y reutilizable. Además, puedes usar la palabra clave await en cualquier lugar del código, sin necesidad de declarar una función async, lo que facilita mucho la escritura de programas asíncronos como si fueran secuenciales.

  • Soporte para API web
    Dispone de manera predeterminada de librerías o APIs del navegador, como fetch, que no están disponibles en node.js, y que era una de las quejas más extendidas entre la comunidad de desarrolladores.

Imagen 0 en Qué es Deno y qué lo hace diferente

Primeros pasos con Deno

Instalación de Deno

No existe un instalador de Deno, sino que lo podemos instalar directamente por línea de comandos.

En la página de Deno tienes los comandos necesarios para la instalación en todos los sistemas operativos, aunque en este post nos centraremos en la plataforma Linux.

Con este simple comando, instalamos Deno en nuestro equipo:

$ curl -fsSL https://deno.land/x/install/install.sh | sudo DENO_INSTALL=/usr/local sh

Una vez finalizada la instalación y cómo nos indicará el propio script, es importante añadir el binario de Deno a nuestro PATH para poder usarlo.
Tras la instalación, podemos comprobar si está funcionando correctamente,ejecutando el comando:
deno --version

Este comando nos devolverá información sobre la versión de Deno, junto con la del motor V8 (de Chrome) y la de TypeScript.

Hola Mundo en Deno

Gracias a que Deno usa TypeScript como lenguaje por defecto, no es necesario ningún tipo de configuración adicional, lo que facilita mucho el desarrollo y la codificación siguiendo los estándares de JavaScript.

Para mostrar un simple hola mundo en Deno, codificamos un pequeño script en TypeScript, para comenzar a probar Deno:

const helloWordDeno = (name: String): String => {
 return "Hello World";
}

console.log(helloWordDeno());

Ahora simplemente necesitamos ejecutar el comando ‘deno run scriptName’, equivalente en node.js al comando ‘node scriptName’:

$ deno run helloWorld.ts
Hello World

Módulos en Deno

Deno no utiliza un sistema “propietario” como require, sino que utiliza el sistema de módulos de ECMAScript, ya que uno de los objetivos de Deno es ser totalmente compatible con los distintos navegadores. Los paquetes se importan directamente con import y la url remota del paquete ya que en Deno no existe un fichero como package.json.

Por ejemplo, imagina que necesitas importar un módulo para el manejo de fechas, para tal cometido simplemente tendrías que escribir:

import { parseDate } from "https://deno.land/std/datetime/mod.ts"

const date = parseDate("01-12-2021", "dd-mm-yyyy");

console.log(date);

Esta instrucción devolvería en la consola del navegador: 2021-12-01T23:00:00.000Z

Fácil, ¿verdad?

Dependencias en Deno

Las dependencias que maneja Deno, se realizan directamente mediante la importación del repositorio descentralizado. En node.js el gestor de dependencias es centralizado. Cuando ejecutamos una aplicación, Deno descarga todas las dependencias, y las almacena en la caché global, por lo que solo son descargadas una única vez.

De todas formas, si se necesita tener todas las dependencias en un único archivo, Deno nos ofrece también la posibilidad de tener un “import map”, similar a soluciones como Webpack alias o TypeScript path alias:

{
 "imports": {
 "path/": "https://deno.land/std/path/"
 }
}

Deno dispone de un namespace u objeto global llamado Deno, que ofrece acceso a una gran cantidad de módulos, evitando la necesidad de importar muchos de ellos.

Si ejecutamos este comando:

console.log(Deno);

En la consola de comandos este listado de módulos que ya están disponibles para su uso:

/* { Buffer, readAll, readAllSync, writeAll, writeAllSync, build, chmodSync, chmod, chownSync, chown, transpileOnly, compile,
bundle, inspect, copyFileSync, copyFile, chdir, cwd, applySourceMap, ErrorKind, DenoError, File, open, openSync.. }*/

Flags de seguridad para la ejecución

Deno, gracias al lenguaje en el que ha sido desarrollado, Rust, es muy seguro. Los programas realizados con Deno se ejecutan en su propio Sandbox y para acceder a elementos como el file system debe solicitar permiso, esto garantiza que los programas maliciosos lo tengan muy complicado en un entorno desarrollado con esta tecnología.

Un ejemplo, el siguiente script intenta acceder al file system para crear un fichero ejemplo.txt :

await Deno.writeTextFile('hello.txt', 'Hello from www.opewebinars.com');

Si ejecutamos el script:

$deno run example.ts

Obtenemos el siguiente mensaje de error:

error: Uncaught PermissionDenied: write access to "test.txt", run again with the --allow-write flag

El error nos indica que el acceso al sistema de archivos debe ser explícito, lo podemos solucionar pasando al propio script los flags —allow-read para lectura, —allow-write para escritura o —allow-network para tener acceso a la red.

Este es listado completo de permisos que necesitamos, para ejecutar cualquier programación desarrollada en Deno:

  • allow-all: Permite todos los permisos.
  • allow-env: Permite acceso a las variables de entorno.
  • allow-hrtime: Permite medición de tiempo de alta precisión.
  • allow-net: Permite el acceso a la red.
  • allow-plugin: Permite la carga de plugins.
  • allow-read: Permite la lectura al sistema de ficheros.
  • allow-run: Permite la ejecución de procesos.
  • allow-write: Permite la escritura en el sistema de ficheros, también permite discriminar por carpeta.

Librería standard y Networking

Deno dispone de una librería estándar muy amplia, que simplifica tareas como interactuar con el sistema de archivos o montar un servidor de forma local. De forma resumida, son todos los módulos que se encuentran disponibles en Deno para cualquier programa, sin necesidad de dependencias de terceros.

No obstante, para utilizar estas librerías es necesario realizar la importación como cualquier otro módulo en el lugar donde se necesiten. Para importarlos, se usa la misma estrategia que las librerías de terceros, es decir, usando la URL.

Se pueden consultar las librerías estándar en https://deno.land/std. En esta web se encuentra el listado de librerías, así como la documentación y el código fuente de cada módulo.

Montar un simple servidor http, es tan sencillo como ejecutar este pequeño script:

import { serve } from "https://deno.land/std/http/server.ts";
const s = serve({ port: 8000 });
for await (const req of s) {
 req.respond({ body: "Hello Deno from server!" });
}

Conclusiones

Como hemos visto, Deno parece un candidato idóneo para desbancar al predominio de Node.js. Todas las decisiones adoptadas van encaminadas a la mejora de uso de node.js, el empleo de Rust, TypeScript, el repositorio distribuído, la apuesta por el estándar, la seguridad… eran los puntos flacos de Node.js, sin embargo el mismo está muy extendido en el desarrollo web, han sido años y años de supremacía, y solo el tiempo dirá, si la comunidad de desarrolladores apostará por Deno en detrimento de NodeJS.

Compartir este post

También te puede interesar

Qué es NodeJS y para qué sirve
Blog

Qué es NodeJS y para qué sirve

Descubre qué es NodeJS, sus beneficios y los problemas que soluciona el uso de este potente entorno de ejecución para JavaScript.

Jesus Lucas Flores