Video Summary and Transcription
La charla de hoy presenta Deno, un tiempo de ejecución de JavaScript de próxima generación con soporte nativo de TypeScript y características mejoradas para el desarrollo en el lado del servidor. Deno ofrece permisos granulares para APIs sensibles e incluye herramientas integradas como un marco de pruebas y un linter. La charla demuestra cómo utilizar Deno con un proyecto existente de Node.js, mostrando la compatibilidad y las características de importación. También se discuten características próximas como la incorporación de módulos de Node en Deno y el manejo de extensiones de archivos. En general, Deno proporciona una transición sin problemas para los desarrolladores de Node y ofrece una variedad de herramientas y características potentes.
1. Introducción a Deno y compatibilidad con Node
Hoy estamos aquí para hablarles sobre el estado de la compatibilidad con Node en Deno. Deno es un tiempo de ejecución de JavaScript de próxima generación con soporte nativo para TypeScript y una serie de características que mejoran el desarrollo de JavaScript en el lado del servidor. Les mostraremos una demostración rápida de Deno y luego nos enfocaremos en las características de compatibilidad con Node. Les mostraremos cómo aplicar estas características en un proyecto existente de Node. Comencemos con una demostración de Deno, donde verán el soporte nativo para TypeScript y cómo configurar un servidor Deno.
¿Qué tal, todos? Mi nombre es Kevin Wendray. Soy parte del equipo de Deno. Me acompaña David Sherritt, quien también es parte del equipo de Deno, trabajando en el tiempo de ejecución de Deno. Hoy estamos aquí para hablarles un poco sobre el estado de la compatibilidad con Node en Deno.
Para aquellos de ustedes que no han oído hablar de Deno antes, es un tiempo de ejecución de JavaScript de próxima generación con soporte nativo para TypeScript, muchas herramientas integradas que veremos en un momento, y una serie de características que creemos que mejoran el estado del desarrollo de JavaScript en el lado del servidor. Pero algo importante que quizás no sepan sobre Deno es cuánto trabajo se ha realizado en la compatibilidad con Node.js como un componente clave del desarrollo de JavaScript en el lado del servidor. En esta presentación, les mostraremos una demostración rápida de Deno para que tengan una idea de cómo funciona y cómo puede diferir de Node.js. Luego, pasaremos la mayor parte de nuestro tiempo explorando algunas características de compatibilidad con Node para que sepan cómo funcionan y cómo pueden aplicarlas en el contexto de un proyecto existente de Node.
De hecho, vamos a tomar un proyecto simple de Node.js que utiliza Express y hacer algunos cambios en él utilizando algunas de las características de compatibilidad con Node que existen en Deno. Así que vamos a empezar. Por cierto, mi amigo David se unirá a nosotros como nuestro comentarista de color. David es en realidad el implementador de muchas de estas características de compatibilidad de las que vamos a hablar. Le haré algunas preguntas y él será mi compañero de programación mientras implementamos algunas de estas cosas. ¿Qué opinas, David? ¿Estás listo para hacer una demostración rápida de Deno? Definitivamente. Muy bien, vamos a hacerlo. Voy a pasar a un proyecto en blanco de Visual Studio Code donde haré una demostración muy rápida de Deno para que tengan una idea de cómo funciona el tiempo de ejecución.
Una de las cosas que notarán de inmediato en Deno es que tiene soporte nativo para TypeScript. Sin necesidad de instalar dependencias ni nada por el estilo, pueden comenzar rápidamente a escribir código TypeScript. Implementaré un servidor de Deno de `Hola Mundo`. En Deno, esto se hace utilizando el espacio de nombres Deno. Hay un comando Deno serve, que nos permitirá configurar una función controladora que tomará un objeto de solicitud estándar de la web y nos permitirá manejar las solicitudes entrantes. Si tenían un Deno JSON, obtendrán la verificación de tipos. Sí, exactamente. Eso es cierto. Quería señalar que podrían notar algunas subrayados y la falta de autocompletado. Y la forma en que puedo solucionarlo, como mencionó David, es agregando un deno.json, que habilitará mi complemento de VS Code para Deno y comenzará a darme algunas sugerencias sobre Deno serve y el espacio de nombres Deno integrado, cosas así. Como primer argumento de Deno serve, nuevamente pasaré un objeto de solicitud. Y en este caso, simplemente devolveré una nueva respuesta que dirá `Hola Mundo`. Y para que el linter de TypeScript esté contento, agregaré un guión bajo al principio para indicar que en realidad no estoy usando este objeto de solicitud. Entonces, una vez más, sin dependencias de terceros, puedo escribir algo de TypeScript que servirá solicitudes HTTP.
2. Características de tiempo de ejecución de Deno y permisos
Deno tiene una característica única de permisos granulares para API sensibles como acceso a la red, acceso al sistema de archivos y acceso al entorno del sistema. Como desarrollador, debes optar explícitamente por estos permisos. Deno también ofrece soporte nativo para TypeScript, un excelente complemento de Visual Studio Code y permisos de tiempo de ejecución.
Y si lo ejecuto con Deno run, notarán que se me solicita permiso. Y esa es otra característica del tiempo de ejecución de Deno, que es única en Deno y no existe en Node de la misma manera, son los permisos granulares para API sensibles como acceso a la red, acceso al sistema de archivos, acceso al entorno del sistema. Esos tipos de permisos debes optar explícitamente por ellos como desarrollador. Entonces, en este caso, voy a decir que sí, estoy dispuesto a permitir el acceso a la red. Y ahora tengo un servidor escuchando en localhost 8000. Así que si abro un nuevo navegador Chrome, que haré aquí en un momento, y voy a localhost 8000, ahí está mi respuesta de hola mundo. Así que eso es solo una demostración rápida de un par de cosas. Tenemos soporte nativo para TypeScript. Tenemos un excelente complemento de Visual Studio Code, que te brinda algo de IntelliSense y otras sugerencias en el entorno de edición. Y tenemos algunos de estos permisos de tiempo de ejecución integrados.
3. Deno Development Experience and Tools
Deno ofrece una experiencia de desarrollo completa para JavaScript en el lado del servidor. Incluye herramientas como un marco de pruebas, un linter y un formateador de forma predeterminada. Deno FMT limpia el formato, y Deno compile genera un ejecutable portátil y autocontenido para ejecutar un servidor local.
Otra cosa que quería mostrarte son algunas de esas características de las que hablé antes. Entonces, Deno trata de proporcionar una experiencia de desarrollo completa para JavaScript en el lado del servidor. Muchas de las herramientas que normalmente tendrías que instalar tú mismo están incluidas en Deno de forma predeterminada. Así que muchas veces, cuando comienzas un nuevo proyecto de Node, tendrás que configurar un marco de pruebas, un linter, un formateador, todas esas cosas.
En Deno, todas esas herramientas te las proporciona directamente. Así que digamos que cometo algunos errores aquí y tengo un formato extraño en mis archivos, o estoy revisando una solicitud de extracción de alguien nuevo en el proyecto. Puedo simplemente usar Deno FMT en este directorio, lo cual va a... Oh, no guardé esos cambios. Culpa mía aquí. Permíteme guardarlos primero, sobrescribir. Y ahora, si ejecuto Deno FMT, eso va a limpiarlo a un formato estándar que puedes esperar ver en todos los proyectos de Deno. Pero además de las pruebas y el formato, también hay algunas cosas realmente geniales como Deno compile.
Entonces, si digo denocompile index.ts, lo que va a hacer es darme un archivo ejecutable que es portátil, completamente autocontenido, que puedo ejecutar para tener un servidor local en funcionamiento. Así que si hago ./.denobasic, ahora tengo ese mismo programa. Ahora estoy ejecutando un servidor en localhost 8000 desde un solo binario. Entonces, una vez más, sin necesidad de instalar herramientas ni dependencias, puedo formatear mi code. Puedo compilarlo en un solo ejecutable. Hay mucho que Deno hace por ti directamente desde el principio.
4. Using Deno with an Existing Node.js Project
Aprende cómo aprovechar las características de compatibilidad de Deno en un proyecto existente de Node.js. Refactoriza el proyecto para utilizar el sistema de módulos ESM de Deno e importar dependencias de npm en línea. Ejecuta la aplicación en Deno y soluciona posibles problemas.
Así que esa es solo una breve descripción de Deno, más o menos lo que hace. Pero no estamos aquí solo para hablar de todas las cosas geniales que vienen incorporadas en Deno. Queremos aprender un poco sobre lo que puedes hacer en el contexto de un proyecto existente de Node.js y aprovechar algunas de las características de compatibilidad que existen en Deno.
Así que volvamos aquí. Este proyecto es un proyecto de Node muy simple y preexistente, que si has usado Node antes, te resultará bastante familiar. Utiliza Express como el framework web ligero que maneja algunas rutas. Tenemos un middleware de análisis de cuerpo (body parser), que nos permite analizar los cuerpos de las solicitudes POST codificados en URL o en JSON. Y luego tenemos un par de rutas configuradas para una API REST ficticia de usuarios.
Y lo que pensé que podríamos hacer para empezar es ver cómo funciona esto en Deno sin cambios y luego refactorizarlo incrementalmente para utilizar algunas de las características de compatibilidad de Deno y hacer que esta aplicación se ejecute realmente. Así que en primer lugar, podemos comprobar que este proyecto funciona ejecutando Node index.js, y parece que el servidor se está ejecutando en el puerto 3000, así que echemos un vistazo a eso. Oh, sí, parece que no hay una ruta allí, pero si hacemos algo como users, nos devuelve una matriz JSON vacía. Así que estamos en un estado de funcionamiento con el servidor de Node, pero ahora intentemos ejecutarlo en Deno y veamos qué sucede. Así que comencemos ejecutando Deno run, y voy a usar la opción -A aquí, que otorga al proceso en ejecución permiso para acceder a todas las API subyacentes. Lo haremos por razones de rapidez. Por lo general, es mejor utilizar solo el conjunto de permisos necesarios para ejecutar el proceso, pero lo ejecutaremos con -A y luego pasaremos index.js. Y parece que ya estamos viendo algunos problemas potenciales. Dice error de referencia, require no está definido.
¿Por qué es eso, David? ¿Por qué require no está definido? En este caso, Deno solo admite ESM, para ser simple. Es como si tuviéramos un sistema de módulos. Es el sistema de módulos estándar en el que JavaScript se ha estandarizado. Necesitamos actualizarlo de CommonJS a ES modules. Sí, exactamente. Entonces, en este caso, tenemos nuestros dos requires aquí arriba en el archivo. Así que si quiero actualizarlos, voy a hacer este import express, y en lugar de usar require, voy a importar express desde npm express. Y este es un especificador de npm, que es la forma en que en una aplicación de Deno importarías tus dependencias en línea. Así que esto es algo que funcionará. En realidad, hay algunas formas diferentes de abordar esto, que podemos ver aquí en un momento. Pero llegaremos allí de manera incremental, diciendo, ya sabes, importar body parser desde npm body parser. Y creo que ese es probablemente nuestro primer obstáculo. Así que ejecutemos la aplicación.
5. Deno Compatibility and Importing Node Modules
Aprende cómo importar el global process del módulo process de Node en Deno para leer variables de entorno. Explora la compatibilidad entre Deno y Node.js realizando cambios menores para ejecutar código de Node en Deno. Descubre la próxima función de traer tus propios módulos de Node.
Oh, y luego hay otro error aquí. De acuerdo, así que error de tipo no puede leer propiedades de indefinido. Entonces process.env.port. En muchas aplicaciones de Node, ya sabes, leerás, ya sabes, el puerto en el que quieres escuchar desde el entorno del sistema. Y eso es un poco diferente aquí. Entonces, ¿de qué se trata este error, David? ¿Por qué no puedo hacer esto?
Sí, no hay un proceso global en Deno. Así que tenemos que importarlo desde el módulo process de Node.
De acuerdo, sí, esa es probablemente la forma más rápida aquí. Así que podríamos hacer eso. También hay una API de Deno para obtener una variable de entorno que podríamos usar en el espacio de nombres de Deno. Pero podemos obtener la importación. ¿Es así, ayúdame desde el principio. Creo que es solo process. Sí, eso es. Así es. Desde, esta vez será un proceso de Node. Entonces, este especificador de Node te permite usar los módulos integrados de Node, como FS, HTTP, todas las demás partes de la biblioteca estándar de Node, que tienen polyfills en el contexto de una aplicación de Deno. Ahora deberíamos tener process.env definido y veamos eso.
Eso es genial. Ahora tenemos el servidor escuchando en el puerto 3000. Y si lo recargamos, podemos ver que estamos empezando a obtener las mismas respuestas. Así que con algunos ajustes, estamos empezando a progresar, pero pensé que sería bueno ver algunas otras características de compatibilidad más allá de lo básico. Pero, ya sabes, es genial ver que con solo unos pocos cambios menores, puedes tomar un code que se ejecutaba en Node y ahora se ejecuta en Deno. Entonces, una cosa que podrías hacer, especialmente si estás migrando desde un proyecto de Node, es en lugar de usar, ya sabes, especificadores de NPM y tener un Deno, lo que realmente está sucediendo en segundo plano aquí es que Deno está descargando, instalando y almacenando en caché versiones de estos módulos de NPM localmente. Es posible que no desees gestionar las dependencias de esa manera. Es posible que ya tengas un package.json, por ejemplo, que ya tenga todas tus dependencias instaladas en él. Entonces hay una forma, David, ¿verdad, de usar las dependencias que están en tu package.json e instaladas en tu carpeta de Node. ¿Cómo lo llamamos? Entonces, hay una forma, como está aquí. En realidad, no necesitas especificar NPM: y Deno resolverá a través del package.json. Pero una cosa, digamos que quieres traer tus propios módulos de Node, usar tu propio administrador de paquetes, eso es la próxima función de traer tus propios módulos de Node (BYONM).
6. Using Node Modules and the Sloppy Imports Feature
Aprende cómo traer tus propios módulos de Node a Deno utilizando la próxima función. Aprende a configurar Deno para usar los módulos de Node instalados por un administrador de paquetes de tu elección. Explora la función de importaciones descuidadas en Deno para importar archivos de otros directorios.
Oh, ¿eso no funcionó? Sí, pensé que, ya sabes, este body parser es sí, ya sabes qué, eso es parte de, creo que esto es parte de Express. Hay un módulo de body parser en NPM. ¿Está en el package.json si no está en el package.json? Sí, no está en el package.json. Esa sería la razón. Entonces está buscando eso. Por eso, sí. Sí. Así que tendríamos que instalar eso con NPM. Lo siento, te interrumpí. ¿Qué ibas a decir?
Oh sí, tenemos la próxima función de traer tus propios módulos de Node y eso permitirá usar el administrador de paquetes de tu elección con Deno. Sí, eso a menudo es útil para traer tus propios módulos de Node si tienes dependencias que dependen de la estructura de la carpeta de módulos de Node de alguna manera. Entonces, si deseas instalar esas dependencias a través de, ya sabes, YARN o PNPM tal vez y aprovechar todas las características y el comportamiento específico de un cliente NPM. Deno puede funcionar bastante bien con una carpeta de módulos de Node después de que haya sido configurada por el administrador de paquetes de tu elección. Y hay algunas formas de configurar ese comportamiento. Pero creo que una de las formas más agradables es a través de, ya sabes, agregar un deno.json a la carpeta o al proyecto en el que estás trabajando. Y dentro de deno.json, hay una propiedad llamada unstable. Y en este momento, la función de traer tus propios módulos de Node está actualmente detrás de una función inestable flag. En Deno 2.0, muchas de estas funciones de compatibilidad, ya sabes, se habilitarán automáticamente y no tendrás que configurarlas en Deno.json. Pero en este caso, podemos habilitar unstable. Es, creo, literalmente llamado traer tus propios módulos de Node, ¿verdad? No, BYONM. Oh, es solo BYONM. OK, entonces esto permitirá que Deno use los módulos de Node que ya están instalados en la carpeta de módulos de Node cuando se ejecute esta aplicación. Entonces, si ejecuto esto, en realidad se utilizará la versión de Express que ya está instalada en la carpeta de módulos de Node. Y puedes ver que podemos actualizar aquí y el servidor sigue funcionando perfectamente.
Otra cosa que pensé que sería útil ver es la función de importaciones descuidadas, que suena un poco gracioso. Pero una de las otras diferencias entre Node y Deno que notarás es para las importaciones de archivos en otros directorios. Digamos que en mi proyecto de Deno que configuré antes, voy a crear un handler.ts. Y en este archivo, es donde voy a crear la función del controlador que quiero usar aquí. Así que voy a tomar esta función del controlador y la voy a exportar como la predeterminada en un módulo de ECMAScript en esta función del controlador. Y luego, si quisiera usar eso en Deno, tendría que importar el controlador desde y luego especificaría un handler.ts y puedes usarlo aquí en su lugar.
7. Imports and File Extensions in Deno
Comprende el comportamiento de las importaciones en Deno, que se asemeja estrechamente al comportamiento del navegador. Aprende cómo importar archivos externos sin un especificador en un proyecto de Node. Configura Deno para manejar las importaciones sin extensiones de archivo utilizando la bandera 'sloppy imports' en Deno.json.
Y si ejecutara eso, por supuesto, eso, vaya, no querría usar la versión compilada. Solo voy a ejecutar Deno y luego haré guión guión, permitir net para permitir el acceso a la red específicamente. Y eso básicamente hará lo mismo. Pero una cosa que notarás de inmediato es que esta importación utiliza la extensión de archivo. Y en Deno, intentamos hacer que el tiempo de ejecución de Deno, ya sabes, sea lo más similar posible al comportamiento del navegador. Los únicos globales, excepto el global de Deno que están en una aplicación de Deno, ya sabes, son globales que tendrías en el navegador. Entonces, ya sabes, fetch y muchos otros globales basados en el navegador están disponibles en Deno. Y la forma en que especificas las importaciones generalmente es mediante la especificación, ya sabes, de una URL completamente calificada. Pero no, en realidad no funciona de la misma manera.
En un proyecto de Node, generalmente importarás, ya sabes, archivos externos sin un especificador. Así que hagamos lo mismo. Crearemos un nuevo archivo llamado, ya sabes, handler.js. Y aquí tendremos que hacer algo ligeramente diferente. Entonces, en Node, si voy a crear un módulo ESM, ya sabes, lo llamaría MJS. Y supongo que, dado que ahora lo estamos ejecutando en Deno, no tengo que hacer eso. Así que lo dejaré con la extensión .js. Y haré algo similar. Voy a, ya sabes, exportar por defecto. Y luego, básicamente, haré que esto sea el mismo controlador que tendríamos aquí. Así que será una función asíncrona de flecha gorda. Así que hará más o menos lo mismo. Y luego aquí puedo decir, ya sabes, importar el controlador desde .slash handler. Pero nuevamente, en un proyecto de Node, probablemente solo diría .slash handler, que es la, ya sabes, que generalmente es la convención en Node. No se usa la, ya sabes, la extensión cuando intentas importar. En realidad, podemos configurar Deno para manejar esto, nuevamente, usando una de esas banderas inestables. Entonces, si vamos a Deno.json, esta se llama, ¿cómo era, David? Es como importaciones descuidadas, con un guion. Así que diremos importaciones descuidadas. Y si habilitamos eso y volvemos a index.js, puedes ver que la línea ondulada roja se ha degradado a una línea ondulada azul porque, ya sabes, no estamos usando la extensión. Pero aparte de los web standards, ¿por qué más, ya sabes, no usamos eso en Deno en general, David? ¿Cuál es el costo de no tener la extensión? Sí. Cuando no tienes la extensión, entonces necesita hacer muchas pruebas.
8. Compatibilidad y Conclusiones
Se recomienda utilizar extensiones explícitas para obtener un mejor rendimiento y simplicidad en el tiempo de ejecución y las herramientas. Deno proporciona una capa para ayudar a refactorizar de forma incremental el código de Node. Ejecuta proyectos de Node existentes en Deno y convierte módulos JS comunes a ESM. Utiliza las importaciones de Node para las funciones incorporadas y explora las características de compatibilidad inestables de Node. Consulta la documentación de Deno y la guía de compatibilidad de Node para obtener más ayuda.
Cada vez que el tiempo de ejecución resuelve ese archivo, tiene que verificar, ¿es esto un directorio? Bien. ¿Hay un index.js? ¿Hay un index.mjs? Y pasar por todas estas posibilidades, hacer esta comprobación, y, ya sabes, imagina multiplicar eso muchas, muchas veces. Hay un costo de performance. Así que sí, recomendamos utilizar extensiones explícitas. Y también es mucho más simple en el tiempo de ejecución y más simple cuando estás implementando cualquier tooling.
Sí. Entonces, en general, cuando haces esto en un proyecto de Deno, te daremos algunas indicaciones suaves que te harán saber, como, oye, probablemente deberías usar extensiones de archivo explícitas. Pero debido a que mucho código de Node no tendrá eso por defecto, tenemos esta capa que te ayudará a refactorizar de forma incremental en esta dirección. Pero una vez que, ya sabes, ejecutamos ese archivo, nuevamente, obtenemos algunas advertencias que nos indican que tenemos una resolución de módulos descuidada. Pero al final del día, Deno nos permite, ya sabes, ejecutar el mismo code dentro del contexto del tiempo de ejecución de Deno.
Así que eso es todo el tiempo que tenemos hoy para hablar de estas características de compatibilidad. Pero lo que recomendamos que hagas es, si tienes un proyecto de Node existente, intentar ejecutarlo en Deno. Y es posible que te sorprendas de lo lejos que puedes llegar sin tener que hacer muchos cambios. Pero en general, lo que debes hacer es convertir cualquier uso de módulos de Common JS a ESM. Deberás utilizar las importaciones de Node para cualquier función incorporada de Node que vayas a utilizar. Y es posible que debas aprovechar algunas características de compatibilidad inestables de Node. En la documentación de Deno en docs.deno.com, hay una lista bastante completa de indicadores de características inestables, varios de los cuales tienen que ver con la compatibilidad de Node. También tenemos una guía de compatibilidad de Node en la docs, donde puedes ver algunas de las cosas que probablemente tendrás que cambiar para ejecutar un proyecto de Node enDeno.
Entonces, nuevamente, creo que eso es todo el tiempo que tenemos hoy. Pero David, muchas gracias por acompañarme y ayudarme a programar en pareja. Y gracias a todos los demás que están viendo la presentación hoy. Y espero que disfruten del resto de la conferencia.
Comments