[英]How dependencies affect Firebase Functions cold start?
Background: I have about 20 Firebase Cloud Functions and they are stored under the default reporoot/functions/src/
folder, which was created when I first init the Firebase project.背景:我有大约 20 个 Firebase 云函数,它们存储在默认的
reporoot/functions/src/
文件夹下,该文件夹是我第一次启动 Firebase 项目时创建的。 Each Cloud Function could have its own unique dependencies and all are specified inside one single reporoot/functions/package.json
每个 Cloud Function 都可以有自己独特的依赖关系,并且都在一个
reporoot/functions/package.json
中指定
Simplified version of the scenario:场景的简化版本:
package.json
, I specify dependencies Lib A , Lib B and dev Dpendencies Lib Xpackage.json
中,我指定依赖项 Lib A , Lib B和dev Dpendencies Lib Xreporoot/functions/src/myFeatureSet1/feature1.ts
, I have a CloudFunction1 by import functionA from LibA
reporoot/functions/src/myFeatureSet1/feature1.ts
,我有一个 CloudFunction1 通过import functionA from LibA
reporoot/functions/src/myFeatureSet2/feature2.ts
, I have a CloudFunction2 by import functionB from LibB
reporoot/functions/src/myFeatureSet2/feature2.ts
,我有一个 CloudFunction2 通过import functionB from LibB
Questions:问题:
reporoot/functions/src/myFeatureSet1/feature1.ts
?reporoot/functions/src/myFeatureSet1/feature1.ts
中 CloudFunction1 引用的唯一库?package.json
under reporoot/functions/src/
?reporoot/functions/src/
下使用相同package.json
开发的所有函数的冷启动时间? Or the deployed Cloud Function will have only what it needs without extra dependencies included?package.json
under reporoot/functions/src/
? reporoot/functions/src/
下使用相同package.json
开发的所有函数的冷启动时间? I think deploying the Cloud Function associates npm i --production
and hence will not include dev Dependencies.npm i --production
,因此不包括开发依赖项。 Is that true?package.json
files for different codebase.package.json
文件的不同代码库。 But following that leads to the following error when I start using the emulator: functions: Failed to load function definition from source: FirebaseError: Error parsing triggers: Cannot find module 'axios' .package.json
package.json
import functionA from LibA
VS import * from LibA
?import functionA from LibA
VS import * from LibA
会有任何代码开始时间差吗? The following assumes your index.ts
is similar to:以下假设您的
index.ts
类似于:
export functionA from LibA
export functionB from LibB
and each function is similar to:每个 function 类似于:
export default functions.https.onRequest(/* ... */);
- If I deploy CloudFunction1 to Firebase, will Lib A , Lib B and Lib X be packaged together in the same deployment zip?
如果我将 CloudFunction1 部署到 Firebase,那么 Lib A 、 Lib B和 Lib X会打包在同一个部署 zip 中吗?
As LibA and LibB are true dependencies, they will be installed when deployed.由于 LibA 和 LibB 是真正的依赖项,因此它们将在部署时安装。 As LibX is in
devDependencies
, it will be skipped.由于 LibX 在
devDependencies
中,它将被跳过。
However, if the source code of LibA, LibB and LibX are all inside the reporoot/functions
folder, they will all get deployed, but not necessarily executed (that would depend on your code).但是,如果 LibA、LibB 和 LibX 的源代码都在
reporoot/functions
文件夹中,它们都将被部署,但不一定执行(这取决于您的代码)。
- Will the number of dependencies impact the cold start time of all functions developed with the same
package.json
underreporoot/functions/src/
?依赖的数量是否会影响
reporoot/functions/src/
下使用相同package.json
开发的所有函数的冷启动时间? Or the deployed Cloud Function will have only what it needs without extra dependencies included?或者部署的云 Function 将只拥有它需要的东西,而不包括额外的依赖项?
By default, dependencies will affect the cold start of all functions.默认情况下,依赖关系会影响所有函数的冷启动。
There are some ways you can structure your code to mitigate this, as covered in this article , this thread or by using a library like better-firebase-functions
.有一些方法可以构建代码来缓解这种情况,如本文、此线程或使用诸如
better-firebase-functions
类的库。
You could also compile your code into many bundles, deploying a single bundle of each function, containing only that function and its dependencies.您还可以将代码编译成多个包,部署每个 function 的单个包,仅包含 function 及其依赖项。 You'd do this using deploy scripts similar to those covered in this thread .
您可以使用类似于此线程中介绍的部署脚本来执行此操作。 This strategy can get messy if not properly thought out.
如果考虑不周,这种策略可能会变得混乱。
- Similar to the Question 2 above, how about dev Dependencies?
与上面的问题 2 类似, dev依赖项如何?
As deployed functions are considered a production environment, you are correct in that devDependencies
will not be installed in the production environment.由于已部署的功能被视为生产环境,因此您是正确的,因为
devDependencies
不会安装在生产环境中。
- How can I split the dependencies among different functions so that each function packages with only the required dependencies?
如何拆分不同函数之间的依赖关系,以便每个 function 仅包含所需的依赖关系?
One of the best approaches to achieve this is to export each function in its own functionX.ts
file (preferably with an accurate name).实现此目的的最佳方法之一是将每个 function 导出到其自己的
functionX.ts
文件中(最好使用准确的名称)。 You can then compile these as standalone bundles, invoke them using lazy loading or group them together with other similar functions.然后,您可以将它们编译为独立包,使用延迟加载调用它们或将它们与其他类似函数组合在一起。 See the resources linked above for further details.
有关详细信息,请参阅上面链接的资源。
If axios
is used by only one function, either spin that function off into its own file/bundle or import it using (await import('axios')).default
when you need it.如果
axios
仅被一个 function 使用,要么将 function 关闭到它自己的文件/包中,要么在需要时使用(await import('axios')).default
。 The error you get suggests that one of your libraries tries to import the axios
library at the top of the file, but when that library gets imported by a non- axios
function (where it's omitted from the package.json
file), it causes a deploy error. The error you get suggests that one of your libraries tries to import the
axios
library at the top of the file, but when that library gets imported by a non- axios
function (where it's omitted from the package.json
file), it causes a部署错误。
I would personally use either node-fetch-native
, node-fetch
or gaxios
(a node-fetch
-based variant of the axios
APIs, used internally to the Firebase libs) instead.我个人会使用
node-fetch-native
、 node-fetch
或gaxios
( axios
API 的基于node-fetch
的变体,在 Firebase 库内部使用)。
- Will there be any code start time difference if I
import functionA from LibA
VSimport * from LibA
?如果我
import functionA from LibA
VSimport * from LibA
会有任何代码开始时间差吗?
Based on just that line, it's hard to tell.仅凭那条线,很难说。 It would depend on the contents of your library and the build tool you are using.
这将取决于您的库的内容和您正在使用的构建工具。 The default compiler will just convert your TypeScript to plain JavaScript regardless of whether its used or not.
默认编译器只会将您的 TypeScript 转换为普通的 JavaScript ,无论它是否使用。 Whereas if your build tool supports "tree shaking", it will only compile what it needs ignoring the unnecessary "leaves" (unused code).
而如果您的构建工具支持“摇树”,它只会编译它需要的内容,而忽略不必要的“叶子”(未使用的代码)。 Popular tree shaking tools include Webpack and Rollup.
流行的摇树工具包括 Webpack 和 Rollup。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.