Búsqueda de sitios web

typescript - Implementación en Firebase - No se puede encontrar el módulo de una dependencia local


Tengo un submódulo llamado shared que se encuentra junto a la carpeta backend (que es la carpeta de funciones en la nube):

He añadido la dependencia local shared en backend/package.json de la siguiente manera:

"dependencies": {
    ...
    "shared": "file:../shared"
}

Ejecuté npm install y me aseguré de que node_modules/shared exista. Sin embargo, cuando ejecuto el siguiente código:

firebase deploy --only functions

Recibo el siguiente error (por Firebase):

Error: Error parsing triggers: Cannot find module 'shared/common'

Try running "npm install" in your functions directory before deploying.

Este error se debe a esta línea:

import { currentWeek } from 'shared/common';

Si cambio el directorio a ../../../shared/common, Firebase se compilará sin ningún error.

compartido/común/index.ts:

export { currentWeek } from './current-week';

compartido/tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "strict": true,
    "removeComments": true
  }
}

backend/tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "declaration": true,
    "outDir": "./dist",
    "module": "commonjs",
    "noImplicitAny": false,
    "removeComments": true,
    "noLib": false,
    "allowSyntheticDefaultImports": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "target": "es6",
    "moduleResolution": "node",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2015",
      "dom"
    ]
  },
  "include": [
    "./src/**/*",
    "../shared/**/*"
  ]
}

¿Por qué recibo este error si SÍ tengo este módulo? ¿Hay algo que me esté perdiendo?

Respuesta #1

Aunque la respuesta de @jrasm91 explica bien la razón de este error, de alguna manera echo de menos la solución al problema aquí.

Supongamos que tienes la siguiente estructura de monorepo

- common
- firebase
  - functions

donde common es un módulo de NodeJS con código común, firebase es la carpeta raíz de tu proyecto de Firebase y firebase/functions es el proyecto de NodeJS de tus funciones.

En firebase/functions/package.json no puedes incluir tu módulo common como

"dependencies": {
    "common": "file:../../common"
}

porque como explicó @jrasm91, la carpeta common está situada fuera de la carpeta functions y por lo tanto no se empaquetará ni se subirá al ejecutar firebase deploy --only functions, lo cual también se explica aquí.

La solución que funcionó para mí es además crear un enlace simbólico de la carpeta common en la carpeta functions

cd firebase/functions
ln -s ../../common common

y luego actualiza el package.json

"dependencies": {
    "common": "file:common"
}

Respuesta #2

En resumen:

  1. node_modules se ignora por defecto, mientras que backend/dist se sube.
  2. npm run build ocurre localmente y npm install ocurre en la nube.
  3. npm install probablemente falla en la nube debido a la falta de la carpeta shared o problemas de ruta incorrecta debido a una estructura de directorios diferente y/o un directorio “raíz” diferente en el entorno de la nube.

O, en más detalle:

Functions tiene un paso de predespliegue que construye (npm run build => tsc) el proyecto de TypeScript localmente y luego envía el resultado a la nube donde las dependencias se instalan (npm install).

Cuando incluyes shared mediante una ruta relativa (../../shared), el código compilado se genera en la carpeta backend/dist después de que el proyecto se construye (localmente) y, por lo tanto, se sube.

Cuando incluyes shared a través de una dependencia local de módulos de nodo, la salida se encuentra en la carpeta backend/node_modules después de que las dependencias son instaladas y, por lo tanto, no se sube ya que node_modules se ignora por defecto.

El otro problema que estás viendo es por qué npm install no puede instalar la dependencia local en la nube. Esto probablemente se deba a (1) no subir shared junto con backend y/o a que la estructura de directorios y rutas relativas en el entorno de la nube es diferente de lo que es localmente.

firebase.json
{
  "functions": {
    "predeploy": ["npm --prefix \"$RESOURCE_DIR\" run lint", "npm --prefix \"$RESOURCE_DIR\" run build"],
    "source": "functions",
    "ignore": ["**/.env", "**/.runtimeconfig.js", "**/.log", "**/node_modules/**"]
  },
  ...
}

Artículos relacionados