MyBotBoxMyBotBox

Cómo se consumen los paquetes @yarlisai

La arquitectura de doble modo: consumo de fuentes del workspace de bun internamente, tarballs de dist de npm externamente.

Cada paquete @yarlisai/* se consume de dos maneras completamente distintas al mismo tiempo. Entender ambos modos explica por qué los despliegues nunca tocan npm, por qué no hay paso de compilación en el desarrollo local y por qué la publicación es una vía paralela en lugar de una dependencia del despliegue.

El mapa de exports

Ambos modos dependen del mismo mapa condicional exports, presente en cada paquete:

{
  "exports": {
    ".": {
      "bun": "./src/index.ts",
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "default": "./dist/index.js"
    }
  }
}

La condición bun se resuelve primero bajo el runtime de Bun y apunta directamente al código fuente TypeScript. Cualquier otro consumidor (Node, bundlers que respetan import/default) obtiene la salida compilada en dist/.

Modo interno — fuentes del workspace

Dentro del monorepo, las apps declaran los paquetes como "@yarlisai/<pkg>": "workspace:*". Los workspaces de Bun enlazan simbólicamente node_modules/@yarlisai/<pkg> a packages/<pkg>/, y la condición de exportación bun resuelve las importaciones directamente a src/index.ts:

  • Sin paso de compilación en dev. Editar packages/email/src/ recarga la app en caliente de inmediato — no hay dist/ que reconstruir ni artefactos desactualizados que perseguir.
  • Docker / CD compila desde fuentes. La imagen de producción (Dockerfile.cloudrun) copia el workspace, compila con turbo y el trazado de salida standalone de Next.js agrupa exactamente los archivos de paquete que importa la app.
  • npm nunca se contacta en los despliegues. Una interrupción del registro, una versión eliminada o una publicación rota no pueden romper un despliegue — la app envía lo que esté en el árbol de git.

Modo externo — tarballs de npm

Los consumidores externos instalan desde npm y obtienen el tarball publicado:

  • El tarball contiene dist/ (más README.md y LICENSE) — nunca src/. La resolución pasa por las condiciones import/default hacia dist/index.js, con los tipos desde dist/index.d.ts.
  • Las compilaciones ejecutan tsc y luego tsc-alias --resolve-full-paths, por lo que las importaciones emitidas llevan extensiones .js explícitas — Node ESM es estricto en esto aunque los bundlers no lo sean.
  • En el momento de la publicación, los rangos de dependencia workspace:* se reescriben a rangos de semver reales (^x.y.z) mediante el workflow de publicación. Sin esa reescritura, npm install fallaría con semver inválido.
  • Los paquetes se publican actualmente como restringidos a la organización npm de Yarlis; el acceso público está planificado.

La ruta externa se ejercita en CI mediante una prueba de humo de consumidor externo que empaqueta cada paquete, instala los tarballs en un proyecto desechable con npm plano e importa cada subruta de exportación bajo Node plano — sin Bun, sin enlaces simbólicos de workspace. De lo contrario, la condición bun ocultaría artefactos dist/ rotos a todos los consumidores internos.

Por qué los dos

  • Los despliegues son inmunes a npm. Los problemas de publicación (y las interrupciones de npm) nunca bloquean el envío del producto — la app consume fuentes a través del workspace.
  • Iteración de desarrollo instantánea. El consumo a nivel de fuente significa que los cambios entre paquetes son una única recarga en caliente, no un ciclo de compilar-enlazar-reiniciar.
  • La vía del framework está desacoplada. El versionado, los changelogs y la publicación se gestionan mediante changesets y workflows de publicación dedicados a su propio ritmo, sin coordinarse con las releases de la app.

El coste del doble modo es que el consumo interno puede ocultar roturas externas — que es exactamente para lo que existen la comprobación de publint y la prueba de humo externa.

Ver también