Organisieren Sie mehrere Funktionen


Wenn Sie Cloud Functions in Ihr Projekt integrieren, kann Ihr Code so erweitert werden, dass er viele unabhängige Funktionen enthält. Möglicherweise haben Sie zu viele Funktionen, um angemessen in eine einzelne Datei zu passen, oder verschiedene Teams stellen möglicherweise unterschiedliche Gruppen von Funktionen bereit, wodurch das Risiko besteht, dass ein Team die Funktionen eines anderen Teams überschreibt oder versehentlich löscht. Cloud Functions bietet verschiedene Möglichkeiten, Ihren Code zu organisieren, um die Navigation und Wartung Ihrer Funktionen zu erleichtern.

Organisieren Sie Funktionen in Codebasen

Sie können die codebase Eigenschaft des Funktionskonfigurationsobjekts in firebase.json verwenden, um eine große Sammlung von Funktionen über mehrere Repositorys oder Unterpakete hinweg innerhalb eines einzelnen Repository-Monorepo-Setups zu verwalten:

# firebase.json
"functions": {
  "codebase": "my-codebase"
  # NOTE: Codebase must be less than 63 characters and can contain only
  # lowercase letters, numeric characters, underscores, and dashes.
}

Die codebase Eigenschaft wird in Firebase CLI v10.7.1 und höher unterstützt.

Verwalten mehrerer Repositorys

Die Eigenschaft codebase kann dazu beitragen, die Verwaltung mehrerer Repositorys zu vereinfachen. Sehen wir uns einen Fall an, in dem Sie über zwei verschiedene Repositorys verfügen, die Funktionen für dasselbe Firebase-Projekt bereitstellen:

$  tree .
├── repoA
│   ├── firebase.json
│   └── functions
│       ├── index.js
│       └── package.json
└── repoB
    ├── firebase.json
    └── functions
        ├── index.js
        └── package.json

Ohne Codebasisanmerkungen hätte Sie die Firebase-CLI aufgefordert, zum Zeitpunkt der Bereitstellung im anderen Repository definierte Funktionen zu löschen:

$ (cd repoA && firebase deploy --only functions)
...
i  functions: preparing functions directory for uploading...
✔  functions: functions folder uploaded successfully
The following functions are found in your project but do not exist in your local source code:
        fn1FromRepoB
        fn2FromRepoB
        ...
? Would you like to proceed with deletion? Selecting no will continue the rest of the deployments. (y/N)

Sie können dieses Problem vermeiden, indem Sie im Abschnitt „Funktionen“ der Datei firebase.json “ in jedem Projekt-Repository eine eindeutige Codebasis-Anmerkung hinzufügen:

# repoA/firebase.json
"functions": {
  "codebase": "repo-a"
}

# repoB/firebase.json
"functions": {
  "codebase": "repo-b"
}

Mit Codebase-Annotation fordert Sie die Firebase-CLI nicht mehr auf, Funktionen zu löschen, die außerhalb Ihres unmittelbaren Repositorys definiert sind:

$ (cd repoA && firebase deploy --only functions)
...
i  functions: preparing functions directory for uploading...
✔  functions: functions folder uploaded successfully
#  Gleefully ignores functions from repoB
i  functions: creating Node.js 16 function fnFromRepoA (us-central1)...
✔  Deploy Complete!

Verwalten mehrerer Quellpakete (Monorepo)

Die Eigenschaft codebase kann dazu beitragen, die Verwaltung mehrerer Quellpakete in einem einzigen Repository zu vereinfachen. Sehen wir uns einen Fall an, in dem Sie ein Firebase-Projektverzeichnis mit Funktionsdefinitionen haben, die über mehrere Unterpakete verteilt sind:

$  tree .
├── firebase.json
├── teamA
│   ├── index.js
│   └── package.json
└── teamB
    ├── index.js
    └── package.json

Dieses Setup eignet sich für die folgenden Anwendungsfälle:

  • Sie haben ein Monorepo- Setup und verschiedene Teams verwalten ihre eigenen Funktionsdefinitionen in einem isolierten Paket.
  • Sie haben eine Funktion mit einer starken externen Abhängigkeit und einer lang andauernden Initialisierung und möchten diese Funktion von anderen latenzempfindlichen Funktionen isolieren.

Um die Monrepo-Einrichtung wie diese zu unterstützen, definieren Sie mehrere Funktionskonfigurationen in firebase.json :

"functions": [
  {
    "source": "teamA",
    "codebase": "team-a"
  },
  {
    "source": "teamB",
    "codebase": "team-b"
  },
]

Mit dieser Konfiguration stellt die Firebase-CLI Funktionen aus allen Paketen in einem einzigen Bereitstellungsbefehl bereit:

$ firebase deploy --only functions
i  deploying functions
i  functions: preparing codebase team-a for deployment
i  functions: preparing codebase team-b for deployment
i  functions: creating Node.js 16 function team-a:helloATeam(us-central1)...
i  functions: creating Node.js 16 function team-b:helloBTeam(us-central1)...
...

Sie können auch eine bestimmte Codebasis bereitstellen:

$ firebase deploy --only functions:team-b
i  deploying functions
i  functions: preparing codebase team-b for deployment
i  functions: updating Node.js 16 function team-b:helloBTeam(us-central1)...
...

Schreiben Sie Funktionen in mehrere Dateien

Wenn Sie mit Cloud Functions beginnen, können Sie Ihre ersten paar Funktionen in einer einzigen Datei zusammenfassen:

index.js

const functions = require('firebase-functions');
exports.foo = functions.https.onRequest((request, response) => {
  // ...
});
exports.bar = functions.https.onRequest((request, response) => {
  // ...
});

main.py

from firebase_functions import https_fn

@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello foo!")

@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello bar!")

Mit mehr als ein paar Funktionen kann es schwierig werden, dies zu bewältigen. Stattdessen können Sie Ihre gesamte Logik für jede Funktion in einer eigenen Datei ablegen und Ihre Quelldatei als Exportliste verwenden:

Node.js

foo.js

const functions = require('firebase-functions');
exports.foo = functions.https.onRequest((request, response) => {
  // ...
});

bar.js

const functions = require('firebase-functions');
exports.bar = functions.https.onRequest((request, response) => {
  // ...
});

index.js

const foo = require('./foo');
const bar = require('./bar');
exports.foo = foo.foo;
exports.bar = bar.bar;

Python

foo.py

from firebase_functions import https_fn

@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello foo!")

bar.py

from firebase_functions import https_fn

@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello foo!")

main.py

from fn_impl.foo import *
from fn_impl.bar import *

Dieses Setup geht von einer Projektverzeichnisstruktur wie der folgenden aus:

my-project
├── firebase.json
└── functions
    ├── fn_impl
    │   ├── __init__.py
    │   ├── foo.py
    │   └── bar.py
    ├── main.py
    └── requirements.txt

fn_impl : Kann einen beliebigen Namen haben

__init__.py : Erforderlich, kann aber leer sein

Gruppenfunktionen

In vielen Projekten können Funktionen in logische Gruppen unterteilt werden, die gemeinsam bereitgestellt und verwaltet werden sollten. Beispielsweise könnten Sie über eine Gruppe von Funktionen verfügen, die zum Melden von Metriken verwendet werden:

metrics.js


const functions = require('firebase-functions');
exports.usageStats = functions.https.onRequest((request, response) => {
  // ...
});
exports.nightlyReport = functions.https.onRequest((request, response) => {
  // ...
});

Sie können diese Funktionen in einer Gruppe zusammenfassen, wenn Sie sie in Ihre index.js Datei exportieren:

index.js


// Export both functions from metrics.js in the "metrics" group:
//  - metrics-usageStats
//  - metrics-nightlyReport
exports.metrics = require('./metrics');

Bei der Bereitstellung wird den Funktionen der Name ihrer Gruppe vorangestellt. In diesem Beispiel würden die Funktionen also metrics-usageStats und metrics-nightlyReport heißen.

Beim Bereitstellen von Funktionen können Sie die Aktion auf eine einzelne Gruppe beschränken:


firebase deploy --only functions:metrics

Nächste Schritte

Weitere Informationen zu Cloud Functions finden Sie unter: