node.js - Migrar un espacio de trabajo NX para usar ESM
Tengo un gran monorepo basado en NX, media docena de aplicaciones, frontend, backend, docenas de librerías. Todo sigue configurado para trabajar con tipos de módulo commonjs, que es lo que siempre producían los generadores de NX, y aún producen.
Sin embargo, cada vez más bibliotecas lanzan versiones "solo ESM", que simplemente no funcionan en absoluto para este monorepo.
Acabo de completar nx migrate latest, estoy en NX 17, Typescript 5.2, Angular 17, pero commonjs simplemente parece quedarse donde está.
Los intentos de actualizar manualmente han fracasado todos, cada vez que arreglo un error aparece el siguiente, a menudo requiriendo cambios a gran escala en más de 1.000 importaciones o cientos de archivos con resultados inciertos.
¿Hay alguna documentación que me esté faltando en algún lugar sobre cómo migrar?
Respuesta #1
Según tengo entendido, la mejor manera de soportar módulos ESM y CommonJS al mismo tiempo es usando TypeScript, lo cual permite ambos y empaquetará las dependencias CommonJS y ESM con allowSyntheticDefaultImports y esModuleInterop.
https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html
Ahora bien, eso no significa que funcione en todas partes, por ejemplo, los proyectos de NodeJS usualmente no incluyen las dependencias, sino que optan por incluir el código de la aplicación y luego instalar las dependencias cada vez, específicamente porque algunas dependencias dependen de verificaciones de hardware/sistema operativo en el momento de la instalación para compilar código por razones de rendimiento, o para usar capacidades de hardware específicas como la GPU.
El artículo en la documentación de TS también menciona Interop en NodeJS, y la idea principal es que no puedes require un verdadero ESM, lo cual no importa para nosotros ya que queremos que nuestro src esté en verdadero ESM.
https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html#interop-in-nodejs
Si entiendo bien, para NodeJS > 16, si defines en package.json el "type": "module", NodeJS asumirá que tu base de código es ESM, y con esModuleInterop importará módulos CommonJS sin problema; el problema es cuando tu código no es ESM verdadero y trata de importar ESM verdadero.