По мере интеграции Cloud Functions в ваш проект, ваш код может разрастись и содержать множество независимых функций. Возможно, функций окажется слишком много, чтобы их можно было разумно разместить в одном файле, или разные команды могут развертывать разные группы функций, создавая риск перезаписи или случайного удаления функций другой команды. Cloud Functions предлагает различные способы организации кода, чтобы упростить навигацию и поддержку ваших функций.
Организация функций в кодовых базах
Для управления большим количеством функций в нескольких репозиториях или подпакетах в рамках одной монорепозитории можно использовать свойство codebase объекта конфигурации functions в firebase.json :
# 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.
}
Свойство codebase поддерживается в Firebase CLI версии 10.7.1 и выше.
Управление несколькими репозиториями
Свойство codebase может помочь упростить управление несколькими репозиториями. Рассмотрим случай, когда у вас есть два разных репозитория, которые развертывают функции в один и тот же проект Firebase:
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
Без аннотаций кода Firebase CLI предложил бы вам удалить функции, определенные в другом репозитории, во время развертывания:
$ (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)
Эту проблему можно избежать, добавив уникальную аннотацию codebase в раздел конфигурации функций файла firebase.json в каждом репозитории проекта:
# repoA/firebase.json
"functions": {
"codebase": "repo-a"
}
# repoB/firebase.json
"functions": {
"codebase": "repo-b"
}
Благодаря аннотациям в коде, Firebase CLI больше не запрашивает удаление функций, определенных за пределами вашего непосредственного репозитория:
$ (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!
Управление несколькими исходными пакетами (монорепозиторий)
Свойство codebase может помочь упростить управление несколькими исходными пакетами в одном репозитории. Рассмотрим случай, когда у вас есть каталог проекта Firebase с определениями функций, разбросанными по нескольким подпакетам:
$ tree .
├── firebase.json
├── teamA
│ ├── index.js
│ └── package.json
└── teamB
├── index.js
└── package.json
Данная конфигурация подходит для следующих сценариев использования:
- У вас настроен монорепозиторий , и разные команды управляют определениями своих функций в изолированном пакете.
- У вас есть функция с сильной внешней зависимостью и длительной инициализацией, и вы хотите изолировать эту функцию от других функций, чувствительных к задержкам.
Для поддержки такой настройки Monrepo определите несколько конфигураций функций в firebase.json :
"functions": [
{
"source": "teamA",
"codebase": "team-a"
},
{
"source": "teamB",
"codebase": "team-b"
},
]
При такой конфигурации Firebase CLI развертывает функции из всех пакетов одной командой развертывания:
$ 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)...
...
Вы также можете развернуть конкретную кодовую базу:
$ 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)...
...
Напишите функции в нескольких файлах.
Начиная работу с Cloud Functions , вы можете разместить свои первые несколько функций в одном файле:
index.js
const functions = require('firebase-functions/v1');
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!")
При наличии более чем нескольких функций управлять этим может быть сложно. Вместо этого вы можете поместить всю логику для каждой функции в отдельный файл и использовать исходный файл в качестве списка экспортируемых переменных:
Node.js
foo.js
const functions = require('firebase-functions/v1'); exports.foo = functions.https.onRequest((request, response) => { // ... });
bar.js
const functions = require('firebase-functions/v1'); 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 *
Данная конфигурация предполагает следующую структуру каталогов проекта:
my-project
├── firebase.json
└── functions
├── fn_impl
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
├── main.py
└── requirements.txt
fn_impl : Может иметь любое имя
__init__.py : Обязательный параметр, но может быть пустым.
Групповые функции
Во многих проектах функции можно разделить на логические группы, которые следует развертывать и поддерживать совместно. Например, у вас может быть группа функций, используемых для формирования отчетов по метрикам:
metrics.js
const functions = require('firebase-functions/v1'); exports.usageStats = functions.https.onRequest((request, response) => { // ... }); exports.nightlyReport = functions.https.onRequest((request, response) => { // ... });
При экспорте этих функций в файле index.js вы можете объединить их в группу:
index.js
// Export both functions from metrics.js in the "metrics" group: // - metrics-usageStats // - metrics-nightlyReport exports.metrics = require('./metrics');
При развертывании функциям будет присвоен префикс в виде имени их группы, поэтому в этом примере функции будут называться metrics-usageStats и metrics-nightlyReport .
При развертывании функций можно ограничить действие одной группой:
firebase deploy --only functions:metrics
Следующие шаги
Чтобы узнать больше о Cloud Functions , см.:
- Обработка зависимостей .
Управление развертыванием функций и параметрами выполнения . См.:
Управление развертыванием функций и параметрами выполнения .