El mapa de exports de package.json se ha convertido en el archivo más infravalorado y, paradójicamente, el que más dolores de cabeza genera al publicar una librería TypeScript. Un error de orden en menos de treinta líneas de JSON puede provocar que miles de usuarios reciban tipos any, fallen al importar con require o vean errores de resolución en entornos específicos. Lo curioso es que las pruebas unitarias pasan, la compilación local funciona y el paquete se publica sin ninguna advertencia por parte de npm. El problema solo se manifiesta cuando el artefacto llega a manos de consumidores reales, cada uno con su propia configuración de módulos, cargador y versión de Node.

La función del campo exports es unificar la resolución de entradas que antes dependía de tres campos independientes: main para CommonJS, module como convenio no oficial para ESM y types para TypeScript. Con exports, un solo mapa decide qué archivo recibe cada consumidor según la condición que active. La clave está en que el orden de las condiciones importa más de lo que la mayoría de los desarrolladores cree. TypeScript recorre las condiciones de arriba abajo y se queda con la primera que coincide. Si la condición types aparece después de import o require, el compilador tomará el archivo JavaScript como fuente de tipos y el resultado será any para cada exportación. La regla es simple pero se incumple constantemente: types debe ir primero en cada bloque condicional, tanto en la entrada raíz como en cada subruta.

Quien desarrolla aplicaciones a medida sabe que la consistencia entre entornos es crítica. Una librería que funciona en desarrollo pero falla en producción es inaceptable. Por eso, al construir software a medida, nuestros equipos integran herramientas de auditoría como attw y publint directamente en el pipeline de integración continua. Estas herramientas analizan el tarball que se enviará al registro, no el código fuente, que es justo donde suelen esconderse los errores. attw prueba el paquete en todos los modos de resolución que soporta TypeScript y reporta exactamente qué combinaciones fallan. publint, por su parte, revisa la estructura del package.json: orden de condiciones, campos heredados que deberían eliminarse y rutas que apuntan a archivos inexistentes. Tres comandos en el prepublishOnly bastan para eliminar toda una categoría de bugs.

La decisión sobre qué formatos publicar también afecta la complejidad del mapa de exports. Una librería nueva debería apostar por ESM-only a menos que tenga una base de usuarios CommonJS consolidada. El soporte dual implica mantener dos builds, dos archivos físicos y condiciones separadas para cada sistema de módulos. En ese escenario, además, conviene declarar archivos de tipos distintos para cada runtime: .d.ts para ESM y .d.cts para CJS. Todo esto se refleja en un exports anidado donde types vuelve a ser la primera condición dentro de cada bloque. La tentación de publicar todo para todos los públicos es comprensible, pero cada formato extra es una superficie de fallo adicional que hay que mantener y auditar.

El bloqueo de importaciones profundas es otra consecuencia que muchos descubren al migrar. Cuando exports está presente, cualquier ruta no listada en el mapa queda prohibida, aunque el archivo exista físicamente en node_modules. Esto convierte el directorio dist en un artefacto privado y la superficie pública se limita a lo que el mapa declara. Es una decisión de diseño excelente para la evolucionabilidad, pero obliga a conocer todos los subpath que los consumidores utilizan antes de añadir el campo exports por primera vez. Herramientas como búsquedas en GitHub del patrón from tu-libreria/ ayudan a identificar esos usos no documentados.

En Q2BSTUDIO aplicamos estos principios tanto en el desarrollo de librerías internas como en los proyectos que entregamos a nuestros clientes. Cuando trabajamos con servicios cloud AWS y Azure, por ejemplo, la correcta exposición de interfaces a través de paquetes compartidos es fundamental para mantener la coherencia entre microservicios. Del mismo modo, al integrar ia para empresas o agentes IA, la fiabilidad de las dependencias impacta directamente en la calidad del producto final. También en proyectos de servicios inteligencia de negocio con Power BI, donde los conectores personalizados deben exponer exactamente los tipos y rutas esperadas, un mapa de exports mal configurado puede paralizar el flujo de datos.

La ciberseguridad también tiene su ángulo aquí: un exports mal escrito puede exponer archivos internos que no deberían ser accesibles desde fuera del paquete. Aunque el bloqueo por defecto ayuda, un error en el patrón comodín o un null mal colocado puede abrir rutas no deseadas. Revisar el mapa con ojo crítico y herramientas automatizadas es parte de una estrategia de seguridad en la cadena de suministro.

La acción concreta para cualquier mantenedor es abrir el package.json de la librería más instalada que gestione y verificar que types esté primero en cada bloque condicional. Luego, añadir attw y publint al CI. Son cambios que se hacen en minutos y que evitan el momento de despertarse con decenas de issues en GitHub. El mapa de exports es pequeño, pero su impacto es desproporcionado: acierta una vez y nadie lo nota, falla una vez y lo pagan todos los usuarios. Merece la pena dedicarle la atención que rara vez recibe.