使用 monorepo 部署到 Firebase 函数

Posted

技术标签:

【中文标题】使用 monorepo 部署到 Firebase 函数【英文标题】:Deploying to Firebase Functions with a monorepo 【发布时间】:2020-07-15 20:33:22 【问题描述】:

根据Firebase Functions with Yarn workspaces,我想使用 Yarn Workspaces 将 monorepo 部署到 Firebase。我可以成功地将“网络”方面部署到 Firebase 托管,它引用了一个共享的“核心”工作区。但是,尝试对 Firebase Functions 上的“函数”工作区执行相同操作会失败。

我正在使用具有以下文件夹结构的 Yarn Workspaces:

packages/           
  core/             // name: firebase-monorepo-core: custom core package
  functions/        // name: firebase-monorepo-functions: firebase functions package
  web/              // name: firebase-monorepo-web: react package

这些已在根package.json 文件中配置:

"workspaces": 
    "packages": [
        "packages/*"
    ],
    "nohoist": [
        "**/firebase-monorepo-core"
    ]

为了在 Firebase 中启用 Yarn 工作区(并因此分享我的 core 包),我使用 nohoist 功能在 functionsweb 中创建指向 core 工作区的符号链接。 twiz的*** answer。

core 包也作为依赖项存在于 functionsweb 中:

"dependencies": 
    "firebase-monorepo-core": "*"

当其中任何一个在本地运行时都没有问题,实际上将 web 包部署到 Firebase 托管工作正常。但是,将 functions 包部署到 Firebase 函数会引发错误:

我创建了一个 Github 存储库 https://github.com/cjmyles/firebase-monorepo 来演示这一点,生成的 web 工作区可以在 https://fir-monorepo.firebaseapp.com 查看。

如果我 yarn pack core 工作区并将其作为压缩包引用到 package.json 文件中,我可以部署 functions 包,但我真的不喜欢那个解决方案,它需要更多自动化它的开销。

如有任何建议可以解决此问题。

【问题讨论】:

嘿,你解决过这个问题吗? 也想知道如何/如果你解决了它 【参考方案1】:

我得到了这个工作,但它是一个痛苦和hacky。到目前为止,它运行良好。我正在使用 NPM 工作区,但这个概念应该适用于节点模块被提升到根文件夹的任何项目。我还在为 CI 和 TypeScript 使用 GitHub 工作流/操作,所以所有这些都可以在这些环境中工作。

使用 TypeScript 的 tsc 构建我的依赖包 将编译后的文件复制到函数文件夹(确切地说是functions/src/domain),以便它们由 Firebase CLI 上传
cp -r packages/domain firebase/functions/src/domain
在函数/package.json 中插入本地依赖项。我正在使用 GitHub 操作支持的 sed
sed -i 's/"dependencies": /"dependencies":  "@mycompany\/domain": "file:src\/domain",/' package.json

在该命令之前,我的 package.json 如下所示:

  "dependencies": 
    "lodash": "^4.17.20",
  ...

在那个命令之后,它看起来像这样:

  "dependencies":  "@mycompany/domain": "file:src/domain",
    "lodash": "^4.17.20",
  ...
然后部署:firebase deploy --only functions

不漂亮,但它可以完全自动化。 ?

【讨论】:

【参考方案2】:

issue 是 firebase-tools 假定您的函数使用的所有包都在 npm 中可用。

一个快速的解决方案是使用firelink。

cd ./packages/functions
yarn add -D @rxdi/firelink

在你的函数 package.json 中为所有共享依赖添加一个等效部分。

  "fireDependencies": 
    "@org/common": "../../packages/common"
  ,

更改部署脚本以使用 firelink 二进制文件

  "scripts": 
    "build": "tsc --build tsconfig.build.json",
    "predeploy": "yarn build",
    "deploy:functions": "firelink deploy --only functions"
  

只是提醒不适用于“devDependencies”,但无论如何您都不应该在生产中需要它们。

更新您的 firebase.json 以运行预部署目标。

  "functions": 
    "predeploy": ["npm --prefix \"$RESOURCE_DIR\" run predeploy"],
    "source": "packages/functions"
  ,

最后删除工作区包中的所有本地 yarn.lock 文件。如果您希望锁定依赖项,请将 npm install 添加到您的预部署步骤。如果有人对此有更好的解决方案,请告诉我。很遗憾yarn 没有能力在工作空间中按需生成锁定文件。

【讨论】:

【参考方案3】:

一个潜在的解决方案是使用 Lerna。

然后,您可以将 core 包发布到私有 GitHub 包,并使用 Lerna 创建指向 core 包的符号链接以进行本地开发。

【讨论】:

以上是关于使用 monorepo 部署到 Firebase 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Heroku 上的库部署 monorepo

在 monorepo Azure 中部署单一服务

使用 yarn 和 ts 3.0 管理 typescript 项目 monorepo

部署在 NX monorepo 中创建的 nestjs 服务器

使用 CircleCI 部署到 Firebase 托管

将环境变量部署到 Firebase 托管