Escuchen, escuchen. vite es un servidor de desarrollo (y algo así como un empaquetador, lo que llaman bundler) y deno es un entorno de ejecución que quiere actuar como un navegador web. Vamos. ¿No lo ven?
Breve repaso
Vamos a presentar rápidamente estas herramientas, para que todos estemos al tanto.
vite
En su página oficial lo describen como una "Herramienta Frontend de Próxima Generación." Es así porque en realidad hace un par de cosas. Tiene incorporado un servidor de desarrollo que toma ventaja de los modulos que ahora son nativos en javascript (ES modules) para ofrecer recargas rápidas e inicios instantaneos. Una de las cosas que lo hacen tan rápido es que en lugar de procesar toda tu aplicación lo que hace es lidiar con un archivo a la vez, y sólo cuando es necesario. Por defecto es capaz de procesar typescript, jsx y modulos de css, así pueden empezar crear inmediatamente. vite también puede empaquetar toda tu aplicación para su uso en "producción" si así lo desean.
deno
deno
es un entorno de ejecución seguro para JavaScript y TypeScript. En otras palabras, puede ejecutar javascript y typescript sin necesidad de un navegador web. Se dice que es seguro porque el código lo ejecuta en un ambiente limitado donde no tiene acceso a tu sistema. Si quieren activar ciertas funcionalidades tienen que dar permiso explícito. Lo otro que hace a deno
interesante es que viene con un empaquetador, un formateador, un "linter," un servidor de lenguage, y otras herramientas. Esta cosa es un ambiente de desarrollo.
¿Por qué quiero usarlos en conjunto?
Por la manera en la que deno
maneja el código de terceros. Verán, cuando quieren utilizar alguna librería tienen que hacerlo de la misma manera que lo harían en un navegador web, usando ES modules con una url (guiño). Algo así.
import * as R from 'https://cdn.skypack.dev/ramda@0.27.1';
Esto es completamente aceptable... hasta que no lo es.
Para un script que sólo necesita un archivo es perfecto. Para proyectos más complejos hay una convención en la que ponen todas sus dependencias en un archivo llamado deps.ts
, no es lo mejor del mundo, pero está bien. También está una funcionalidad experimental llamada import-maps, esto mejoraría mucho el panorama.
A partir de la versión 1.8.0 de
deno
los import-maps ya son considerados estables. Notas del lanzamiento.
En fin, quiero trabajar con esto.
import * as R from 'ramda';
Y quiero instalar esa cosa, ramda
, usando un manejador de dependencias "real." En la actualidad eso significa usar npm (en deno esto casi un pecado). El problema es que deno
no le gusta npm
.
vite al rescate
Digamos que queremos usar ramda
. De nuevo, queremos usar npm
para instalarlo, entonces lo que hacemos es esto.
npm install ramda@0.27.1
Ahora creamos un script, lo llamaremos main.js
.
import * as R from 'ramda';
const increment = R.map(x => x + 1);
console.log(increment([1, 2, 3]));
Miren qué bonito. Eso es lo que queremos. Ahora es momento de instalar vite
.
npm install -D vite@2.0.4
Primero hagamos una prueba. Vamos a crear un archivo html, index.html
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="module" src="/main.js"></script>
</body>
</html>
Usamos vite
.
npx vite
Si todo salió bien deberían tener esto en sus pantallas.
vite v2.0.4 dev server running at:
> Local: http://localhost:3000/
> Network: http://192.168.0.000:3000/
ready in 347ms.
Ahora si visitan http://localhost:3000/
y luego revisan en la consola del navegador deberían tener esto.
[ 2, 3, 4 ]
Bien. Genial. ¿Ahora cómo llevamos eso a deno
? Mencioné que deno
quiere actuar como un navegador. ¿Saben qué hace un navegador? Ejecuta código que viene de una url.
Pero esperen un segundo. Antes de que hagan cualquier cosa, sólo en caso de que no quieran "contaminar" el caché global que deno
usa en su sistema, les sugiero que cambien la variable de entorno DENO_DIR
. En su terminal hagan esto.
export DENO_DIR="$PWD/.cache"
Me disculpo con los usuarios de windows, no conozco el equivalente de esto en
cmd
opowershell
.
¿En dónde estábamos? Usando deno
. Esto es lo que haremos, en lugar de usar el archivo main.js
que está en nuestro directorio lo que hacemos es usar main.js
que vite
está sirviendo.
deno run "http://localhost:3000/main.js"
deno
debería mostrarles.
Download http://localhost:3000/main.js
Download http://localhost:3000/node_modules/.vite/ramda.js?v=2e8a2ea4
[ 2, 3, 4 ]
¡Funciona! Hemos usado exitosamente una librería que viene de npm en deno
. Es todo un logro. Pero no celebremos mucho aún. Ahora sólo por diversión, ejecuten ese comando otra vez.
[ 2, 3, 4 ]
Debió mostrarle eso, y sólo eso. No apareció nada de "download http://...". Todo está bien. Ahora bien cambien algo en main.js
.
import * as R from 'ramda';
const increment = R.map(x => x + 1);
-
- console.log(increment([1, 2, 3]));
+ console.log('hello');
Ejecútenlo nuevamente.
¿Les apareció el texto hello
? Apuesto a que no, y ahora quieren saber la razón.
Es porque deno
está tomando main.js
de un servidor (localhost) está descargando el código en su caché (la carpeta DENO_DIR), y no intentará descargarlo otra vez a menos que la url cambie. ¿Cómo resolvemos esto? Sólo se me ocurre esto.
deno run "http://localhost:3000/main.js?t=$RANDOM"
Aquí estoy usando un parámetro t
para añadir un número aleatorio a la url, esto técnicamante crea una url nueva cada vez que ejecutamos el comando.
Este es el mismo método que usa vite
para invalidar el caché de un navegador.
Si fingimos que tenemos un archivo llamado other.js
y lo usamos en main.js
.
import { other } from './other.js';
Cuando cambiemos algo en other.js
vite
va a añadir una estampa de tiempo en la url del archivo. Entonces, cuando se produce un cambio deno
les mostrará algo como esto.
Download http://localhost:3000/other.js?t=1614653342379
Y ahí lo tienen, un ambiente de desarrollo con vite
y deno
.
¿Qué hacemos después?
Ya sé, ya sé, en algún momento van a querer usar esta "aplicación" que estamos desarrollando sin tener que depender de vite
. La solución parece ser simple. En este caso usamos el comando deno bundle
, lo que hará será tomar todo el código necesario para la aplicación y lo colocará en un solo archivo.
deno bundle "http://localhost:3000/main.js?t=$RANDOM" dist.js
Ahora si ejecutan dist.js
deberían obtener los resultados esperados.
deno run dist.js
Tengan presente
Sólo en caso de que no lo sepan. Incluso si pueden descargan cualquier librería desde npm
no significa que va funcionar en deno
. A veces esa librería que quieren usar no es compatible.
Conclusión
Este pequeño experimento funciona, o al menos en los ejemplos triviales que hice. No recomiendo que empiecen a desarrollar aplicaciones para producción con esta combinación, aún no. Para proyectos personales y otros experimentos es perfectamente aceptable.