简体   繁体   English

依赖关系如何影响 Firebase 函数冷启动?

[英]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:场景的简化版本:

  1. In the package.json , I specify dependencies Lib A , Lib B and dev Dpendencies Lib Xpackage.json中,我指定依赖项 Lib A , Lib Bdev Dpendencies Lib X
  2. In reporoot/functions/src/myFeatureSet1/feature1.ts , I have a CloudFunction1 by import functionA from LibAreporoot/functions/src/myFeatureSet1/feature1.ts ,我有一个 CloudFunction1 通过import functionA from LibA
  3. In reporoot/functions/src/myFeatureSet2/feature2.ts , I have a CloudFunction2 by import functionB from LibBreporoot/functions/src/myFeatureSet2/feature2.ts ,我有一个 CloudFunction2 通过import functionB from LibB

Questions:问题:

  1. 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 中吗? Or only Lib A will be included in the package to be deployed because that is the only library referred by CloudFunction1 in reporoot/functions/src/myFeatureSet1/feature1.ts ?或者只有 Lib A将包含在要部署的 package 中,因为这是reporoot/functions/src/myFeatureSet1/feature1.ts中 CloudFunction1 引用的唯一库?
  2. Will the number of dependencies impact the cold start time of all functions developed with the same 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?或者部署的云 Function 将只拥有它需要的东西,而不包括额外的依赖项?
  3. Similar to the Question 2 above, how about dev Dependencies?与上面的问题 2 类似, dev依赖项如何? Will the number of dev Dependencies impact the cold start time of all functions developed with the same package.json under reporoot/functions/src/ ? dev Dependencies 的数量是否会影响reporoot/functions/src/下使用相同package.json开发的所有函数的冷启动时间? I think deploying the Cloud Function associates npm i --production and hence will not include dev Dependencies.我认为部署云 Function 关联npm i --production ,因此不包括开发依赖项。 Is that true?真的吗?
  4. If the answer for Q2/Q3 above is Yes, how can I split the dependencies among different functions so that each function packages with only the required dependencies?如果上面 Q2/Q3 的答案是肯定的,我该如何拆分不同函数之间的依赖关系,以便每个 function 只包含所需的依赖关系? I read https://firebase.google.com/docs/functions/organize-functions#managing_multiple_source_packages_monorepo and it shows different package.json files for different codebase.我读了 https://firebase.google.com/docs/functions/organize-functions#managing_multiple_source_packages_monorepo ,它显示了不同的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' .但是,当我开始使用模拟器时,会导致以下错误: functions: Failed to load function definition from source: FirebaseError: Error parsing triggers: Cannot find module 'axios' Note: One of my Cloud Function uses axios and I put it inside one package.json注意:我的一个云 Function 使用 axios,我把它放在一个package.json
  5. Will there be any code start time difference if I 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(/* ... */);
  1. 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文件夹中,它们都将被部署,但不一定执行(这取决于您的代码)。

  1. Will the number of dependencies impact the cold start time of all functions developed with the same 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?或者部署的云 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.如果考虑不周,这种策略可能会变得混乱。

  1. 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不会安装在生产环境中。

  1. 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-nativenode-fetchgaxiosaxios API 的基于node-fetch的变体,在 Firebase 库内部使用)。

  1. Will there be any code start time difference if I import functionA from LibA VS import * from LibA ?如果我import functionA from LibA VS import * 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM