使用expressjs优化firebase功能冷启动

使用expressjs优化firebase功能冷启动,firebase,express,google-cloud-platform,google-cloud-functions,cold-start,Firebase,Express,Google Cloud Platform,Google Cloud Functions,Cold Start,我试图找出如何优化firebase功能的冷启动时间。阅读之后,我想尝试一下,但我意识到本文专门针对HTTPOnRequest函数的基本用法,没有给出使用express的示例 但似乎没有一个明确的答案。我看到文章的作者Doug实际上对这个问题发表了评论,他提到要为应用程序中的每个路由创建一个动态导入,因为onRequest()只允许将应用程序作为其唯一的参数传递,但我并不完全理解他所说的,除了在没有express应用程序的情况下使用基本API之外。理想情况下,我可以使用express,这样我就可以

我试图找出如何优化firebase功能的冷启动时间。阅读之后,我想尝试一下,但我意识到本文专门针对HTTPOnRequest函数的基本用法,没有给出使用express的示例

但似乎没有一个明确的答案。我看到文章的作者Doug实际上对这个问题发表了评论,他提到要为应用程序中的每个路由创建一个动态导入,因为onRequest()只允许将应用程序作为其唯一的参数传递,但我并不完全理解他所说的,除了在没有express应用程序的情况下使用基本API之外。理想情况下,我可以使用express,这样我就可以更好地控制api url路径,并使用express提供的一些实用程序

有谁能给我举一个如何使用express的例子和Doug的例子吗?即使我必须为每条路线定义一个新的express应用程序,我也同意。只是不知道如何以这种方式配置它


编辑:明确地说,目标是优化所有函数调用的冷启动,而不仅仅是http路由调用。据我所知,Doug的示例消除了使用onRequest声明的单个路由预加载的导入,但它没有显示在通过express定义路由时如何实现这一点。

假设您拆分的每个路由器都在其自己的文件中定义,如下所示:

/$FUNCTIONS\u DIR/routes/some-route-handler.js
从“快递”导入快递;
const router=express.router();
/* ... 定义路由*/
导出默认路由器;
然后,您可以使用该中间件仅在需要时加载每个路由处理程序模块

函数lazyRouterModule(modulePath){
返回异步(req、res、next){
让路由器;
试一试{
路由器=(等待导入(modulePath)).default;
}捕捉(错误){
//加载模块时出错,请让next()处理
下一个(错误);
返回;
}
路由器(req、res、next);
}
}
在子功能文件中,您可以使用该中间件创建express应用程序并连接路由

/$FUNCTIONS\u DIR/fn/my-express.js
从“快递”导入快递;
常量app=express();
app.use('/api',lazyRouterModule('/routes/api.js'));
app.use('/profiles',lazyRouterModule('/routes/profiles.js');
导出默认应用程序;
然后在主功能文件中,按需连接子功能文件:

/$FUNCTIONS\u DIR/index.js
从“firebase函数”导入*作为函数
export const myExpress=functions.https
.onRequest(异步(请求、响应)=>{
wait(wait import('./fn/my express.js')).default(请求、响应)
});
export const newUserData=functions.firestore.document(“/users/{userId}”)
.onCreate(异步(快照、上下文)=>{
wait(wait import('./fn/new user data.js'))。默认值(快照,上下文)
});
当像这样延迟加载模块时,您将希望从公共文件延迟加载
firebase admin
,这样您就不会多次调用
initializeApp()

/$FUNCTIONS\u DIR/common/firebase-admin.js
从“firebase管理员”导入*作为管理员;
admin.initializeApp();
导出=管理;
在任何想要使用
“firebase admin”
的函数中,您可以使用以下方法从此处导入它:

/$FUNCTIONS\u DIR/fn/some-function.js或$FUNCTIONS\u DIR/routes/some-route-handler.js
从“./common/firebase admin”导入*作为管理员;
//正常使用admin,它已经初始化

既然我们在根全局范围中导入它,那么现在是否会加载所有其他函数调用的express依赖项?express是否是由于onRequest框架支持下面的express api而已经作为全局范围的一部分加载的东西?我将在稍后有机会的时候再次讨论,但是按照您提出问题的方式,您正在为每个路由寻找动态导入,这意味着您有一个大型的基于express的云函数,并不是说您正在分别为每个云函数寻找动态导入。后者更难支持Node 10迁移过程中的环境变量更改,因此我明天必须仔细阅读笔记。明白了,感谢您的帮助。我把这个问题修改得更清楚一点。如果我正确阅读了上面的解决方案,唯一的问题就是express被全局加载,但除此之外,所有内容都在动态导入之后进行了优化。如果可能的话,使express自身动态加载似乎很棘手。@KaneChong使用所建议的子函数结构进行了更新。在查看环境变量后,节点8云函数的
函数名
环境变量似乎在以后的节点版本中被重命名为
K\u服务
。看来这个方案在这些年后仍然有效。它不是一个凌乱的索引文件,而是允许您在文件树中将函数导出为
some function.func.js
,使用父文件夹作为它们的部署组。