Bugs en producción: qué archivo carga tu bundler

El bug que solo aparece en producción: resolución de módulos y package.json exports

Hay una categoría especial de bugs que ningún desarrollador quiere enfrentar: los que no se reproducen en local. Todo pasa las pruebas, el equipo hace el deploy con confianza, y entonces en producción el comportamiento es completamente distinto. Nadie tocó el código de la aplicación. El mismo import, el mismo módulo. Pero algo cambió.

Este escenario, planteado como desafío técnico por Google for Developers, toca un punto ciego muy común en equipos de desarrollo: la resolución condicional de módulos según el entorno de ejecución. No es un problema nuevo, pero sigue atrapando a equipos experimentados porque ocurre en una capa que pocos revisan durante el desarrollo cotidiano.

En este artículo exploramos qué está pasando exactamente, por qué la respuesta no es obvia, y cómo evitar que este tipo de bug llegue a afectar tus sistemas en producción.

¿Qué archivo se carga realmente en producción?

El desafío plantea un package con dos archivos: debug.js y prod.js. Localmente, el import carga lo que esperas. En producción, el comportamiento cambia sin que nadie haya modificado el código de la aplicación. ¿Cuál se carga?

La respuesta correcta es prod.js, y la razón está en el campo exports del package.json. Este campo permite definir condiciones de resolución: dependiendo de si el entorno es development o production, el runtime o el bundler cargará un archivo diferente para el mismo import.

Un ejemplo simplificado de cómo se ve esto en un package.json:

  • Condición development: resuelve a ./src/debug.js
  • Condición production: resuelve a ./src/prod.js

Cuando Webpack, Vite o Node.js detectan que el build es de producción, aplican automáticamente la condición correspondiente. Tu código no cambia. El archivo que se ejecuta, sí.

Por qué esto varía según el runtime o bundler

Aquí está el crédito extra del desafío: la respuesta puede ser diferente según la herramienta que uses. No todos los entornos interpretan las condiciones del campo exports de la misma manera.

Node.js respeta las condiciones de exports de forma nativa desde la versión 12, pero requiere que el paquete las defina correctamente. Webpack 5 introdujo soporte para exports condicionales y aplica la condición production cuando el modo está configurado como tal. Vite, por su parte, tiene su propia lógica de resolución que puede diferir sutilmente. Y en entornos como Jest o Vitest para pruebas, si no se configura explícitamente la condición del entorno, pueden terminar cargando el archivo equivocado — lo que explica por qué los tests pasan pero producción falla.

El problema no está en que esta funcionalidad exista: es útil y poderosa. El problema está en que muy pocos equipos la conocen lo suficientemente bien como para anticipar sus efectos durante el desarrollo y la revisión de código.

Cómo aplica esto en empresas de Perú y LATAM

En proyectos de desarrollo de software para empresas medianas en la región, este tipo de problema aparece con más frecuencia de lo que se reporta. Los equipos trabajan con stacks modernos — TypeScript, React, Node.js, Flutter para mobile — pero no siempre tienen procesos formales para validar el comportamiento de resolución de módulos entre entornos.

El escenario más común que vemos: un equipo desarrolla una integración o un módulo interno, todo funciona en el entorno local y en staging, y al hacer deploy a producción aparece un comportamiento inesperado que tarda horas en diagnosticar. El costo no es solo técnico: es tiempo del equipo, posible afectación al negocio, y confianza perdida en el proceso de deployment.

Esto aplica también en proyectos con Odoo cuando se desarrollan módulos personalizados con dependencias JavaScript, y en aplicaciones móviles con Flutter donde los flavors de build pueden afectar qué configuración se carga. El concepto subyacente es el mismo: el entorno de ejecución determina qué código corre, no solo qué código escribiste.

¿Cómo aplica esto en tu empresa?

Si tu equipo trabaja con JavaScript, TypeScript o cualquier stack moderno con bundlers, hay acciones concretas que puedes implementar hoy:

  • Audita los package.json de tus dependencias clave: revisa si tienen campo exports con condiciones. Si lo tienen, asegúrate de entender qué archivo se carga en cada entorno.
  • Configura explícitamente las condiciones en tu bundler: no asumas que Webpack, Vite o tu herramienta de testing aplican las mismas condiciones automáticamente. Valida la configuración.
  • Incluye pruebas de smoke en el entorno de producción: después de cada deploy, ejecuta un conjunto mínimo de verificaciones que confirmen que los módulos críticos se están comportando como se espera.
  • Documenta las diferencias entre entornos: si tu proyecto usa resolución condicional de módulos intencionalmente, deja eso documentado en el README o en la guía de onboarding del equipo.

Estas prácticas no eliminan todos los bugs de entorno, pero reducen significativamente el tiempo de diagnóstico cuando algo falla en producción.

Conclusión

Los bugs que solo aparecen en producción son los más costosos, no porque sean técnicamente complejos, sino porque se descubren en el peor momento posible. La resolución condicional de módulos es una funcionalidad legítima y poderosa del ecosistema JavaScript moderno, pero exige que los equipos la entiendan y la gestionen conscientemente.

Conocer cómo tu bundler y tu runtime resuelven los imports según el entorno es parte del conocimiento técnico que diferencia a un equipo que hace deploys con confianza de uno que cruza los dedos cada vez que sube a producción.

En Consultoría-Ti trabajamos con equipos de desarrollo en Perú y América Latina para fortalecer exactamente este tipo de prácticas: arquitectura de software sólida, procesos de deployment confiables y decisiones técnicas que soporten el crecimiento del negocio. Si tu equipo enfrenta desafíos similares o quieres revisar tus procesos de desarrollo, conversemos.

Fuentes y Referencias

Google for Developers — In production, which file actually gets loaded? (YouTube Shorts)



✨ Contenido generado con ContentFlow — Consultoría-Ti

Compartir
Etiquetas
Agentes de IA: el peligro real cuando los LLMs actúan