管理多個函式


將 Cloud Functions 整合到專案後,您的程式碼就能擴充為包含多個獨立函式。您可能為單一檔案設定過多函式,以合理方式納入單一檔案中,或者不同團隊可能部署不同的函式群組,造成一個團隊覆寫或意外刪除其他團隊的職務的風險。Cloud Functions 提供不同的程式碼整理方式,可讓您更輕鬆地瀏覽及維護函式。

整理程式碼集中的函式

您可以使用 firebase.json 中函式設定物件的 codebase 屬性,管理單一存放區單體存放區設定中的多個存放區或子套件的大型函式集合:

# 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.
}

Firebase CLI 10.7.1 以上版本支援 codebase 屬性。

管理多個存放區

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)

如要避免發生這個問題,請在每個專案存放區的 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!

管理多個來源套件 (monorepo)

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');
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');
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 *

這項設定假設專案目錄結構如下:

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');
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-usageStatsmetrics-nightlyReport

部署函式時,您可以將動作限制為單一群組:


firebase deploy --only functions:metrics

後續步驟

如要進一步瞭解 Cloud Functions,請參閱: