gpt4 book ai didi

javascript - Easy Firebase Cloud Functions 组织

转载 作者:行者123 更新时间:2023-12-05 06:12:42 26 4
gpt4 key购买 nike

问题

在研究了 Firebase 文档、视频、StackOverflow、大量文章之后……以“简单”的方式组织多个(大量)云功能并不明显。特别是,由于官方 Firebase 文档没有提供清晰的愿景/建议。实际上,真正的问题是缺乏关于如何从一开始就设置具有大量功能的 Firebase 项目的清晰文档。

考虑到以下几点,我试图找到一种简单的方法:

解决方案?

从手动部署云功能到使用 JavaScript 进行简单的初始 CLI 设置,我尝试了以下文件结构并取得了一些成功:

[project]/
- functions/
- index.js
- src/
- functionA.js
- functionB.js
- ...
...

索引.js

结构基于官方文档:https://firebase.google.com/docs/functions/organize-functions

const functions = require('firebase-functions');

const functionA = require('./src/FunctionA');
exports.FunctionA = functionA.FunctionA;

const functionB = require('./src/FunctionB');
exports.FunctionB = functionA.FunctionB;

函数A.js

使用 https://gist.github.com/saintplay/3f965e0aea933a1129cc2c9a823e74d7#file-index-js

const functions = require('firebase-functions');
const admin = require('firebase-admin');

// Prevent firebase from initializing twice
try { admin.initializeApp() } catch (e) {console.log(e);}

exports.FunctionA = ...

函数B.js

const functions = require('firebase-functions');
const admin = require('firebase-admin');

// Prevent firebase from initializing twice
try { admin.initializeApp() } catch (e) {console.log(e);}

exports.FunctionB = ...

问题

  • 这是一个切实可行的解决方案吗?
  • 与 async/await 导入相比,是否存在任何性能问题?
  • 围绕 admin.initializeApp() 的 try-catch block 是否是一个干净的实现?
  • Typescript 的等效解决方案是什么?
  • 冷启动时间:通过 Firebase CLI 部署时,我注意到 Google Cloud Console 的“Cloud Functions”部分中所有云函数实例都包含所有其他函数的源代码
    • 在云控制台中手动创建函数时,每个函数只有自己的一段代码需要部署/初始化/执行
  • 有什么优化建议吗? (例如 index.js 的可维护性)

最佳答案

我会尽量一起回答你的问题:

组织您的函数文件和文件夹是一个见仁见智的问题。您始终可以使用 require() 方法为您的 index.js 引入其他功能。您无需遵循有关此的官方文档。从 another stackoverflow question 查看这个不错的解决方案

需要注意的是不要在全局范围内包含其他函数不使用的require语句。例如,如果您有一个使用 Nodejs 库的函数,而另一个函数不使用该库,并且您在全局范围内需要该库,那么冷启动以获取该库将影响这两个函数:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

// need the admin sdk
exports.functionA = ...

// doesn't need the admin sdk
exports.functionB = ...

在上面的示例中,获取 admin sdk 的冷启动将应用于这两个函数。您可以通过以下方式对其进行优化:

const functions = require('firebase-functions');


// need the admin sdk
exports.functionA = functions.https.onRequest((request, response) => {

const admin = require('firebase-admin');
...
})


// doesn't need the admin sdk
exports.functionB = ...

我们只在需要admin sdk的函数中使用,以减少冷启动和优化内存使用。

您甚至可以通过在 typescript 中使用动态导入来进一步改进这一点,这将在调用时获取库或模块代码,而不是在 JS 中使用 require 进行静态导入。

import * as functions from 'firebase-functions'

// this variable will help to initialize the admin sdk once
let is_admin_initialized = false

export const functionA =
functions.https.onRequest(async (request, response) => {
// dynamically import the Admin SDK here
const admin = await import('firebase-admin')

// Only initialize the admin SDK once per server instance
if (!is_admin_initialized) {
admin.initializeApp()
is_admin_initialized = true
}

...

})

关于:

try { admin.initializeApp() } catch (e) {console.log(e);}

我相信这是一个有效的实现,这将检查错误:

The default Firebase app already exists. This means you calledinitializeApp() more than once without providing an app name as thesecond argument. In most cases you only need to call initializeApp()once. But if you do want to initialize multiple apps, pass a secondargument to initializeApp() to give each app a unique name.

除非你想对这个错误做些什么,否则我建议使用带有 bool 标志的上面的实现:is_admin_initialized = false

关于冷启动,它是serverless架构中无法避免的恶果,暂时没有办法消除它,但可以通过以下不同的做法来减少:

1- 对于具有 1 或 2 个依赖项的 JS 函数,您应该期望大约 8 秒左右的冷启动,但这完全取决于这些包大小的结束。

2- 冷启动可能发生在不同的情况下,例如:

  • 你的函数还没有被触发,比方说在你的函数部署之后
  • 您的功能实例已关闭,没有空闲实例可以接收即将到来的请求根据我的经验,Cloud Functions 可以让实例闲置几分钟,大约 10m 左右。
  • 您的函数正在自动缩放和配置新实例

3- 不要包含您的函数不需要的库(依赖项),并且仅将依赖项的范围限定在需要它们的函数中,使用 JS 中的 require() 静态导入或 TS 中的动态异步导入。请记住,有时您不需要使用整个库,而只需使用其中的一个函数。在这种情况下,尝试只从库中导入该函数而不是整个函数。

关于javascript - Easy Firebase Cloud Functions 组织,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63553965/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com