Video Summary and Transcription
Esta charla analiza las complejidades y terminología del sistema de módulos, las discrepancias entre TypeScript y Node, y cómo solucionar los errores de TypeScript con el paquete Helmet. También explora la resolución de módulos y las discrepancias de tipos, los desafíos con el soporte de TypeScript y Node, y la necesidad de mejoras en paquetes populares.
1. Introducción a los módulos y terminología
Hola a todos. Mi nombre es Andrew y he estado en el equipo de TypeScript durante los últimos cuatro años. Hoy hablaremos sobre las complejidades del sistema de módulos y la terminología asociada, como ESM y CommonJS. Es importante estar familiarizado con las opciones de resolución de módulos y las diferencias entre Node.16 y Node.Next.
Muy bien. Hola a todos. Y gracias por unirse a mí para hablar sobre módulos. Mi nombre es Andrew. He estado en el equipo de TypeScript durante los últimos cuatro años, y tenemos mucho de qué hablar hoy en poco tiempo, así que eso es suficiente sobre mí. Y creo que todos sabemos que las complejidades del sistema de módulos son súper interesantes y divertidas, así que no hay tiempo para convencerte, pero si viste la charla de Mark Erickson y no tuviste suficiente, esta es definitivamente la charla para ti. Antes de comenzar, hay un poco de terminología que debemos cubrir. Voy a usar el término ESM o el acrónimo ESM alrededor de cien veces en esta charla. Eso significa Módulo ECMAScript. ESM es el sistema de módulos que se agregó a la especificación del lenguaje JavaScript en 2015. Y puedes reconocerlo por las palabras clave import y export. El otro sistema de módulos que discutiremos es CommonJS o CJS. Ese es el estándar de la comunidad que fue popularizado por Node antes de que existiera ESM. Si alguna vez has visto require y module.exports, eso es CommonJS y aún es compatible con Node. También tendré que mencionar algunas extensiones de archivo durante esta charla. Y como pueden superponerse con otros acrónimos, intentaré recordar pronunciarlos con un punto al principio. Será algo útil si estás al menos vagamente familiarizado con algunas opciones de resolución de módulos y TypeScript. Node.16 y Node.Next son actualmente idénticos, así que puedo llamarlos por cualquiera de los dos nombres. Son la única buena opción para Node moderno y no solo significa emitir módulos ES. Esa es una idea equivocada común. Históricamente, el que se llamaba Node era el que todos usaban para casi todo, pero realmente
2. Entendiendo el error de TypeScript con Helmet
Vamos a analizar un confuso error de TypeScript con la dependencia de NPM Helmet. Cuando se compila a CommonJS, todo funciona bien. Sin embargo, al cambiar a módulos ES, se produce un error en el que helmet ya no se puede llamar. Vamos a investigar más a fondo ejecutando el código.
Helmet no se ha mantenido al día con las características modernas. Vamos a echar un vistazo a un error de TypeScript un tanto confuso aquí. Estoy mirando la dependencia de NPM llamada Helmet. Acabo de copiar y pegar el ejemplo del archivo README aquí. Esto se compila con TSC y se ejecuta en Node sin problemas. Puedes ver que actualmente estoy compilando a CommonJS. Si quiero cambiar a módulos ES aquí, puedo hacerlo agregando el campo type module a mi propio package JSON para el proyecto. Pero cuando hago eso y vuelvo aquí, ahora obtengo este confuso error de TypeScript que dice que helmet ya no se puede llamar. Si juego lo suficiente con esto, veré TypeScript
3. Entendiendo la Discrepancia entre TypeScript y Node
Esta parte discute la discrepancia entre TypeScript y Node al importar el paquete Helmet. Explica cómo TypeScript y Node determinan el formato de archivo y las relaciones entre diferentes tipos de archivos en JavaScript. También explora qué sucede al exportar e importar código transpilado de ESM a CommonJS.
Estoy ejecutando esto. Esto no se ve bien para mí, pero vamos a ejecutarlo y ver qué sucede. Sí, esto se bloquea en Node. Por otro lado, si volvemos a la forma en que estaba donde typescript se queja, pero ejecutamos esto, funciona perfectamente. Parece haber una discrepancia aquí entre typescript y Node, y no podemos satisfacer a ambos al mismo tiempo. Al ver esto, es razonable preguntarse si esto es un error de typescript o si los tipos están mal. Para determinar eso por nosotros mismos, primero necesitamos aprender algunas cosas de antecedentes. La primera es cómo typescript y Node saben qué archivo estamos mencionando cuando decimos importar helmet o require helmet. Será más fácil de explicar esto con el campo de exportación y el archivo package JSON cuando volvamos al código, así que dejémoslo por un momento. La segunda es la detección del formato del módulo. Creo que mencioné que Node admite tanto ESM como CommonJS, por lo que necesita una forma de determinar qué archivo es de qué formato, y lo hace puramente por la extensión del archivo. Un archivo .mjs siempre será ESM, un archivo .cjs siempre será CommonJS, y un archivo .js, tenemos que consultar el package JSON más cercano y si tiene el campo especial type module, será ESM, de lo contrario, CommonJS. Muy bien. La tercera cosa son las relaciones entre los diferentes tipos de archivos con los que trata JavaScript. Cuando ejecutas TSC en un archivo input.ts, obtienes un archivo output.js y un archivo output.d.ts, que se llama archivo de declaración. Cuando publicas código para que otras personas lo consuman, generalmente quieres enviarles el código JavaScript compilado sin procesar. De esa manera, su tiempo de ejecución no necesita otro paso de compilación antes de ejecutarlo. Pero luego si ese usuario también está usando TypeScript ellos mismos, o simplemente un editor con funciones de lenguaje inteligente impulsadas por TypeScript, quieres darles este archivo de declaración, que contiene todo lo que necesita saber sobre el archivo JavaScript, incluyendo los tipos que se han eliminado del archivo original de TypeScript. Debido a que estos dos resultados se producen juntos al mismo tiempo, cuando el compilador o editor del usuario ve un archivo de declaración, um, en realidad ni siquiera necesita ir a buscar y asegurarse de que el archivo JS existe. Debido a esta relación, simplemente puede asumir que existe, saber todo lo que necesita saber sobre la estructura y los tipos, y también la extensión del archivo. Cuando ve .d.ts, sabe que debe haber un archivo .js allí. Y lo mismo ocurre con las extensiones de archivo específicas del formato que discutimos anteriormente. Un archivo .mts produce un archivo .mjs, y obtenemos un archivo .d.mts junto a eso. Y luego tenemos un análogo para las versiones de CommonJS aquí. Puede parecer que estoy enfatizando un punto relativamente simple aquí, pero te sorprendería la cantidad de problemas que tienen como causa raíz el romper esta relación de alguna manera.
Lo siguiente que necesitamos aprender es qué sucede si intentamos compilar esta exportación predeterminada a CommonJS. Las exportaciones predeterminadas en ESM son solo una forma especial de importación con nombre con una sintaxis especial adjunta. Entonces, lo único que haremos es adjuntar una asignación de propiedad con nombre aquí en module.exports con el valor que estamos exportando. Y luego también definiremos esta bandera aquí que simplemente dice, hey, he sido transpilado de ESM a CommonJS. Nuestro archivo de declaración, por otro lado, conserva esta sintaxis de ESM. Bien, casi terminado aquí. Lo último que necesitamos ver es qué sucede cuando intentamos importar esa misma exportación predeterminada transpilada que acabamos de ver. Entonces aquí tenemos nuestra exportación predeterminada transpilada a CommonJS nuevamente. Y si estamos importando esto en otro archivo que también se está compilando a CommonJS, entonces tiene sentido que lo que deberíamos obtener con una importación predeterminada allí sea el valor que exportamos por defecto.
4. Entendiendo las Importaciones y Exportaciones Predeterminadas en Node
La importación predeterminada y la exportación predeterminada deben coincidir. Al importar un módulo CommonJS en Node, se devuelve todo el objeto module.exports. Para diagnosticar el error entre TypeScript y Node, debemos examinar los archivos que están buscando, comenzando con el archivo package.json de Helmet.
La importación predeterminada y la exportación predeterminada deben coincidir. Así que solo debería obtener hola mundo. Y las transformaciones que se aplican al compilar esto desde una importación predeterminada a una declaración require aseguran que eso se cumpla. Por otro lado, cuando hacemos esto en un módulo ES real en node, node no entiende que nuestro módulo de exportación aquí está fingiendo ser ESM. Y en node, cuando importas por defecto un módulo CommonJS, lo que obtendrás siempre es todo el objeto module.exports.
Entonces aquí, puedes ver que he registrado el module.exports y obtengo un objeto con una propiedad llamada default. Y eso es lo mismo que obtendría en node si hiciera una importación predeterminada real de esta falsa exportación predeterminada. Obtendría la propiedad module.exports con este default. Bien, ahora deberíamos saber lo suficiente como para poder diagnosticar este error por nosotros mismos. Si queremos entender la diferencia entre TypeScript y node, necesitamos saber qué archivos están buscando cada uno de ellos.
Entonces, primero, veamos el archivo package.json de Helmet. Bien, tenemos este campo de exportaciones nuevamente que mencionamos brevemente antes. Lo que vamos a hacer aquí es echar un vistazo a esta clave de punto. Y esto coincide con la ruta. Entonces, como estoy importando Helmet y no como Helmet slash utils, la ruta de punto coincide y entraremos aquí y veremos algunas condiciones. Así que vamos a fingir que estamos resolviendo como node primero. Estamos resolviendo una importación, no un require. Y lo que node va a hacer es mirar cada una de estas condiciones de arriba a abajo y seguir hasta que encuentre una que coincida. Entonces, la importación coincide porque estamos resolviendo una importación. Así que entraremos en este objeto y veremos algunas condiciones anidadas. Los tipos no coinciden. No es una de las condiciones que node establece aquí. Así que lo omitirá y comprobará el valor predeterminado. El valor predeterminado siempre coincide con todo. Entonces, node se resolverá a index dot MJS. Ahora, si estamos resolviendo como TypeScript, hacemos exactamente el mismo proceso con una excepción. TypeScript siempre coincide con la condición de tipos. Por lo general, no es necesario establecer la condición de tipos a menos que coloques todos tus archivos de declaración en un directorio completamente separado del JavaScript. Pero está aquí y coincide. Entonces, TypeScript se resolverá a index dot D dot TS.
5. Resolviendo la Discrepancia de Formato y Arreglando los Tipos
Por cierto, hay una bandera de línea de comandos para TypeScript llamada trace resolution. Esto mostrará todo lo que está sucediendo. Ahora que sabemos qué archivos están en juego, hablemos del formato por un momento. Tenemos una discrepancia de formato. Si TypeScript supiera que este archivo está intentando tipar un módulo ES real, vería esta exportación como helmet por defecto y sabría que cuando lo importemos por defecto, funcionará como esperamos. Pero lo que TypeScript piensa es que este archivo representa un archivo Common JS que hace exports.default igual a helmet. Si soy el autor de la biblioteca, parece que todo está funcionando en tiempo de ejecución y solo necesito cambiar algo en la configuración de los tipos para solucionar este problema. El autor de la biblioteca Helmet ya ha solucionado este problema y lo ha resuelto mucho antes de que comenzara esta charla, por eso me siento cómodo analizándolo un poco en una conferencia. En lugar de repetir el trabajo que hizo y arreglar los tipos para que coincidan con el JavaScript existente, podría ser más divertido e instructivo para nuestros propósitos intentar romper el JavaScript existente para que coincida con los tipos existentes. La forma en que lo haré es comenzar haciendo que las extensiones coincidan. Sabemos que el archivo index.d.ts representa un archivo .js, así que eliminaré la M aquí. Y nuestra demostración no va a tocar el lado de require, pero haré que coincida también. Bien, el index.js que acabamos de poner aquí en realidad aún no existe. Así que lo crearé. Y como dijimos antes, sabemos que este archivo debe ser Common JS. Así que comenzaremos copiando el contenido de index.cjs aquí y asumiremos que está bastante cerca y luego lo comprobaremos. Vimos que teníamos esa exportación helmet por defecto, que vemos representada aquí como exports.default igual a helmet. Así que esto se ve bien. Creo que el único problema aquí es que esta línea está sobrescribiendo eso.
Por cierto, hay una bandera de línea de comandos para TypeScript llamada trace resolution. Esto mostrará todo lo que está sucediendo. Así que no tienes que recordar esto si solo quieres ver a qué está resolviendo TypeScript.
Ahora que sabemos qué archivos están en juego, hablemos del formato por un momento. Sabemos que node en este archivo .js lo interpretará como ESM debido a la extensión de archivo. El archivo .d.ts, por otro lado, sabemos que representa un archivo .js debido al triángulo que vimos antes en los tipos de archivo de TypeScript. Y el formato de ese archivo .js se determinaría por el campo module en el archivo package.json, pero no hay ninguno aquí en este package.json en ningún lugar. Así que sabemos que ese archivo JavaScript debe ser Common JS. Aquí tenemos una discrepancia de formato.
El archivo index.mjs de node sabemos que debe ser ESM y el archivo de declaración de tipos sabemos que representa un archivo Common JS. Y si echamos un vistazo a los propios tipos, nos preocupa esta parte de la exportación helmet por defecto. Y esto termina de explicar lo que estábamos viendo. Si TypeScript supiera que este archivo está intentando tipar un módulo ES real, vería esta exportación como helmet por defecto y sabría que cuando lo importemos por defecto, funcionará como esperamos. Sabes, tenemos una exportación por defecto. La importamos por defecto y la podemos usar sin problemas. Pero lo que TypeScript piensa es que este archivo representa un archivo Common JS que hace exports.default igual a helmet. Y si ese es el caso, cuando lo importemos por defecto en Node, todavía necesitaremos hacer ese .default adicional para acceder a la propiedad exports.default ya que solo estamos obteniendo la vista de module.exports en su totalidad.
Entonces, si soy el autor de la biblioteca, parece que todo está funcionando en tiempo de ejecución y solo necesito cambiar algo en la configuración de los tipos para solucionar este problema. Pero para revelar un pequeño spoiler, el autor de la biblioteca Helmet ya ha solucionado este problema y lo ha resuelto mucho antes de que comenzara esta charla, por eso me siento cómodo analizándolo un poco en una conferencia. Así que en lugar de repetir el trabajo que hizo y arreglar los tipos para que coincidan con el JavaScript existente, podría ser más divertido e instructivo para nuestros propósitos intentar romper el JavaScript existente para que coincida con los tipos existentes. La forma en que lo haré es comenzar haciendo que las extensiones coincidan. Sabemos que el archivo index.d.ts representa un archivo .js, así que eliminaré la M aquí. Y nuestra demostración no va a tocar el lado de require, pero haré que coincida también. Bien, el index.js que acabamos de poner aquí en realidad aún no existe. Así que lo crearé. Y como dijimos antes, sabemos que este archivo debe ser Common JS. Así que comenzaremos copiando el contenido de index.cjs aquí y asumiremos que está bastante cerca y luego lo comprobaremos. Vimos que teníamos esa exportación helmet por defecto, que vemos representada aquí como exports.default igual a helmet. Así que esto se ve bien. Creo que el único problema aquí es que esta línea está sobrescribiendo eso.
6. Solucionando el Error de TypeScript con Helmet
Nos encontramos con un error de TypeScript al usar el paquete Helmet. Al realizar cambios en el código JavaScript, pudimos hacer coincidir los tipos y resolver el error. Este patrón de una biblioteca CommonJS asignando a exports.default es común, y los tipos advierten correctamente a los usuarios que están importando en Node.esm. Para simplificar el proceso de análisis, creé una herramienta llamada rthetypeswrong que verifica la resolución de módulos e identifica las discrepancias entre TypeScript y el tiempo de ejecución. Helmet 7.0 ha resuelto los problemas al tipar correctamente los archivos index.cjs e index.mjs.
Entonces, simplemente vamos a eliminarlo. Y creo que ahora deberíamos tener acuerdo. Volviendo a nuestro archivo de entrada, recordemos que no tocamos los tipos en absoluto. Aún esperamos ver este error de TypeScript, pero lo que deberíamos ver es que si TypeScript nos está dando un error, Node también se va a bloquear. Así que vamos a construir y ejecutar eso. Y sí, esta vez, helmet no es una función. Y si en cambio hacemos lo que TypeScript nos está diciendo que deberíamos hacer, helmet.default, y luego construimos y ejecutamos esto, esto ahora funciona.
Ok, ¿por qué pasamos por este tipo de ejercicio tonto de hacer un cambio probablemente indeseable en el JavaScript para que coincida con los tipos? Bueno, a veces cuando las personas me presentan un problema como este y les explico lo que está sucediendo en los tipos, dirán algo así como, sabes, parece que TypeScript está siendo demasiado pedante aquí. Claramente podía encontrar los tipos antes, y mi JavaScript de CommonJS y ESM son casi idénticos. Así que si TypeScript puede encontrar el archivo, simplemente, ya sabes, entiende lo que quiero decir y no me hagas pasar por tantos obstáculos. Pero lo que hemos demostrado aquí es que los tipos no están incorrectos per se. No son inválidos. Simplemente describen una biblioteca diferente a la que teníamos aquí. Describen la que acabamos de hacer a través de nuestros cambios. Y este patrón de, esencialmente, una biblioteca CommonJS que asigna a exports.default es bastante común. Es posible que el autor de la biblioteca no haya tenido la intención de hacer esto, pero lo he visto varias veces en la práctica. Y cuando los tipos para eso son correctos, advierte correctamente a los usuarios que están importando en Node.esm que necesitarán de manera no intuitiva, pero legítimamente, este extra.default para acceder a lo que creen que necesitan acceder. Entonces, aunque todos ustedes ahora son expertos en resolución de módulos e interoperabilidad, puede ser demasiado pedir que todos los usuarios o incluso todos los autores de bibliotecas sean expertos en este tema.
Así que hice una herramienta que puede hacer parte de este análisis por ti. rthetypeswrong es una herramienta que descarga un paquete NPM y luego, para cada modo de resolución de módulos admitido por TypeScript, realiza esencialmente el análisis que acabamos de hacer manualmente. Verifica a qué está resolviendo el compilador de TypeScript y a qué está resolviendo el tiempo de ejecución, analiza cada uno de esos archivos y verifica las discrepancias. Aquí estábamos viendo Helmet 6.1.2 y vemos que cuando estamos importando desde ESM en el modo Node 16, resolvemos a tipos de CommonJS pero JavaScript de ESM. Y eso es exactamente lo que vimos. Y mencioné que Helmet ya ha solucionado esto. Así que echemos un vistazo a eso. En Helmet 7.0, no vemos problemas y CommonJS se resuelve a CommonJS y ESM a ESM. Esto se ve genial. Y como no nos molestamos en arreglar los tipos nosotros mismos, podemos ver cómo el autor de la biblioteca solucionó esto. Aquí vemos que tanto los archivos index.cjs como index.mjs ahora están tipados con su propio archivo de declaración con la extensión correcta. Así que TypeScript puede ser consciente de todos los archivos que están allí y conocer los formatos de todo.
7. Analizando la Resolución de Módulos y las Discrepancias de Tipos
Ahora hay una versión de línea de comandos de la herramienta, lo que facilita su integración en los procesos de publicación o la verificación de paquetes locales. Probamos los cambios realizados en Helmet utilizando la herramienta y solucionamos las discrepancias entre los tipos y JavaScript. Sin embargo, la versión ESM se resuelve a la versión Common JS, lo cual no es el resultado deseado. Al analizar los paquetes de npm a lo largo del tiempo, se observan mejoras para los usuarios en todos los grupos, excepto para los usuarios de node ESM, que enfrentan errores en más de una cuarta parte de las dependencias de tipos. Los problemas en la lista ESM incluyen declaraciones de CommonJS que intentan representar JavaScript de ES y resoluciones sin tipos. Este último es un problema más grave, ya que TypeScript no puede encontrar las declaraciones de tipos que se envían con el paquete. Estos problemas pueden ser relativamente fáciles de solucionar, a diferencia de otros que requieren ajustes en los sistemas de compilación. Los problemas surgen de la adopción rápida de la sintaxis ESM antes de que los implementadores y TypeScript se pusieran al día, lo que llevó a suposiciones incorrectas sobre la interoperabilidad de los dos formatos. Las soluciones alternativas para la falta de soporte de TypeScript también se convirtieron en problemas cuando TypeScript introdujo los modos Node-16 y Node-next. Es importante tener en cuenta que cuando se consideran incorrectos los tipos de un paquete, no se trata de un juicio sobre las publicaciones anteriores.
También hay una versión de línea de comandos de esta herramienta ahora. Por lo tanto, es fácil integrarla en su proceso de publicación o verificar un paquete local. Por diversión, probemos eso en los cambios que hicimos en Helmet. Ejecutaré attw y luego pack, y lo ejecutaremos en node-module-slash-helmet. Puedes ver aquí que hemos solucionado las discrepancias, no se encontraron problemas entre los tipos y JavaScript, pero a diferencia de la versión anterior, a diferencia de en Helmet 7, podemos ver que la versión ESM de las cosas se resuelve a la versión Common JS de la biblioteca. Eso no es un problema, pero no es la solución que probablemente Helmet quería hacer, que era, ya sabes, hacer que ESM se resuelva al ESM que ya está allí.
Lo bueno de hacer todo este análisis en los paquetes npm es que nos brinda una forma natural de ver muchos datos a lo largo del tiempo. Ejecuté rthetypeswrong en los 6,000 principales paquetes npm tal como existían el primero de cada mes desde enero del año pasado, desglosados por algoritmo de resolución de módulos. Podemos ver que las cosas están mejorando para los usuarios en todos los grupos aquí, con la ligera excepción del aumento reciente en node 10, que proviene de paquetes que dejan de admitir esto. Por otro lado, las cosas no se ven bien para los usuarios de node ESM, con más de una cuarta parte de las dependencias de tipos mostrando algún tipo de error. Esto nos pone en una situación difícil, porque si la comunidad va a migrar a ESM, y creo que debería hacerlo, pero de todos modos, ya está sucediendo. Sería muy bueno si pudiéramos animar a los usuarios a hacer esa transición primero antes que las bibliotecas, pero eso es difícil de vender como usuario de TypeScript si hacer el cambio va a romper una cuarta parte de tus dependencias.
Si desglosamos los problemas que estamos viendo en esa lista ESM de problemas aquí, podemos ver un poco más de matices. Esta línea verde es el tipo de problema que acabamos de ver, donde las declaraciones de CommonJS intentan representar JavaScript de ES. Parece que esto está aumentando a largo plazo, pero por otro lado, está intercambiando uno por uno con esta línea naranja, que son resoluciones sin tipos. Esto significa que el paquete estaba enviando declaraciones de tipos, pero TypeScript no pudo encontrarlas en absoluto. Y ese es un problema peor, aunque los números agregados no lo demuestren realmente. No tenemos tiempo para entrar en qué son cada uno de estos problemas que el tipo fuerte puede detectar, pero señalaré que el segundo problema más frecuente aquí, a diferencia de algunos de los otros, creo que son relativamente fáciles de solucionar la mayor parte del tiempo. Algunos de los otros requieren ajustes en los sistemas de compilación, y estos a menudo son solo una corrección de una línea. Tienen que ver con mezclar export equals y export default en archivos de declaración. Entonces, ¿de dónde vienen todos estos problemas en primer lugar? Las lagunas en esta línea de tiempo son la mejor explicación que se me ocurre. Escribir sintaxis ESM se volvió increíblemente popular muy temprano en 2014, antes de que se publicara la especificación final de ESM en 2015. Y esto es normal, probar características del lenguaje temprano es parte del proceso de TC39. Pero lo que vimos fue una adopción muy rápida de escribir código ESM en la comunidad con un largo retraso antes de que los implementadores pudieran ponerse al día. Y luego otro largo retraso después de eso antes de que TypeScript pudiera ponerse al día con Node. En todo este tiempo, ya sea que lo supieran o no, las herramientas que te permiten escribir sintaxis ESM y generar common.js estaban codificando estas suposiciones implícitas sobre cómo iban a interoperar esos dos formatos en tiempo de ejecución real. Y no todas esas suposiciones resultaron ser correctas. Al mismo tiempo, entre 2019 y 2022, cuando los paquetes querían enviar ESM y declaraciones de tipos, tuvieron que idear soluciones alternativas para la falta de soporte de TypeScript aquí. Pero una vez que TypeScript se puso al día y lanzó los modos Node-16 y Node-next, esas soluciones alternativas se convirtieron en problemas en sí mismas. Es importante entender que cuando digo que los tipos son incorrectos para un paquete, no es un juicio sobre lo que se publicó en el pasado.
8. Desafíos con el Soporte de TypeScript y Node
Muchos de los problemas que vemos se pueden atribuir al soporte rezagado de TypeScript para Node. Me he estado enfocando en este espacio de problemas durante aproximadamente un año, trabajando en difundir información y mejorando la herramienta ¿Los Tipos están Equivocados?. Ahora, estoy buscando tener un impacto más directo en los problemas existentes en los paquetes populares.
Es solo una observación sobre lo que funciona o no funciona ahora. De hecho, muchos de los problemas que vemos tienen sus raíces en el soporte rezagado de TypeScript para Node. Por lo tanto, este espacio de problemas ha sido mi principal enfoque durante la mayor parte de un año. Hasta ahora, la mayor parte de lo que he estado haciendo ha sido para difundir información desde ¿Los Tipos están Equivocados? hasta la documentación oficial de TypeScript. Creo que esa fase de mi trabajo está llegando a su fin y tengo algunas mejoras en el plan de ¿Los Tipos están Equivocados? de las que estoy emocionado. Pero anticipando un cambio hacia la búsqueda de formas de tener un impacto más directo en algunos de los problemas existentes que vemos en los paquetes populares. Entonces, si ya estás familiarizado con este espacio o simplemente quieres aprender y participar en eso, por favor contáctame y podemos intentar solucionar algunos de estos problemas juntos. Si eres un autor de bibliotecas, te recomiendo encarecidamente que ejecutes ¿Los Tipos están Equivocados?, la CLI, como parte de tu proceso de publicación para que puedas detectar algunos de estos problemas antes que tus usuarios, y si eres un usuario y notas uno de estos errores extraños en una de tus dependencias y ¿Los Tipos están Equivocados? puede detectar que algo está sucediendo aquí, considera abrir un problema contra la biblioteca. Solo recuerda buscar duplicados y proporcionar una reproducción clara y, lo más importante, sé amable con los mantenedores. Te advertí al principio que esta charla iba a ser bastante abstracta y ligera en consejos prácticos. Así que intentaré terminar con algunas recomendaciones concretas. En primer lugar, en mi opinión, es hora de adoptar ESM solo para nuevos proyectos. Al menos, no asumas automáticamente que necesitas enviar CommonJS. Cuando solo produces un formato de módulo y especialmente cuando es ESM y especialmente cuando lo produces con TSC, prácticamente estás garantizado de estar inmune a todos los diferentes tipos de problemas que ¿Los Tipos están Equivocados? puede detectar en las bibliotecas populares. En segundo lugar, si estás interesado en más validación como parte de tu proceso de publicación, recomiendo publint.dev como contraparte de ¿Los Tipos están Equivocados?. Cubre un montón de reglas no relacionadas con TypeScript que puedes verificar para asegurarte de que estás configurando correctamente tu package JSON. Y luego no tuvimos tiempo para entrar en esto, pero creo que hay muchas razones por las que deberías pensarlo dos veces antes de publicar un paquete dual ESM CommonJS. Pero si es necesario, te recomiendo investigar DNT, que es el publicador de paquetes de Deno para Node. Tiene algunas características únicas, como ejecutar tu conjunto de pruebas de Deno tanto en los paquetes de salida CommonJS como ESM. Eso puede darte una mayor confianza, especialmente cuando lo combinas con algo como ¿Los Tipos están Equivocados?, para que si te encuentras con un problema que se está introduciendo en tus paquetes, lo detectarás antes de publicarlo. Por último, este es un tema en el que veo mucha negatividad y sentimientos de impotencia. No puedo negar que estas cosas pueden ser complicadas, pero definitivamente no son más difíciles que aprender un nuevo framework de front-end cada semana o hacer aritmética en el espacio de tipos o centrar verticalmente un div. Veo a todos ustedes haciendo cosas impresionantes y complicadas todos los días, y sugiero que veas este tipo de espacio desordenado como una oportunidad para aprender cosas nuevas o incluso convertirte en un experto en un área que realmente necesita más expertos. Así que, gracias por escuchar y nos vemos en la sesión de preguntas y respuestas y en las salas de discusión.
Comments