【问题标题】:Firebase Functions with Yarn workspaces带有 Yarn 工作区的 Firebase 函数
【发布时间】:2019-04-21 15:16:14
【问题描述】:

我们开始采用使用 yarn 工作区的 monorepo 设置,我们希望在其中包含我们的 firebase 功能。回购结构类似于:

repo
    node_modules <- all dependencies
    packages
        core
        commom
        functions <- firebase functions

所以,这个设置有两个问题:

  1. 函数的依赖项与函数的入口文件不在同一个文件夹中
  2. 这些功能依赖于其他包,例如 repo 中的 corecommom,因此 yarn 符号链接从 node_modules 到 repo 中的包。

有什么我可以处理的吗?

【问题讨论】:

    标签: node.js firebase google-cloud-functions monorepo yarn-workspaces


    【解决方案1】:

    使用 Yarn 2 不会获取 node_modules 并将其放入相应的 functions 目录中(就像在 functions 目录中调用 npm i 一样)。因此,当调用 firebase deploy --project default --only function 时,node_modules 文件夹会丢失,firebase 会对此进行抱怨并中止部署过程并出现以下错误(或类似错误):

    Error parsing triggers: Cannot find module [...]
    Try running "npm install" in your functions directory before deploying.
    

    目前有两个 github 问题正在跟踪此问题:

    在上述两个问题中,firebase 用户提出了几个巧妙的解决方法,例如使用 webpack 创建包含发布中所有本地包的构建,或使用 rsync 或其他工具在发布前重新连接包。

    如果可能的话,另一个解决方案是不提升您的项目包。您可以这样做,将以下两个指令添加到您的 .yarnrc.yml 文件中。

    # yarnrc.yml
    
    # disables yarn's plugnplay style and uses node_modules instead
    nodeLinker: node-modules
    # makes sure the node_modules are not hoisted to the (monorepo) project root
    nmHoistingLimits: "dependencies"
    

    上述两个指令在yarnrc configuration docs中解释如下:

    nmHoistingLimits 定义可以吊起包裹的最高点。工作区之一(不要将包提升到依赖于它们的工作区)、依赖项(不会将包提升到每个工作区的直接依赖项之外)或无(默认情况下,尽可能多地提升包)。可以通过 installConfig.hoistingLimits 字段覆盖每个工作区的此设置。

    nodeLinker 定义应该使用什么链接器来安装 Node 包(用于启用 node-modules 插件),其中之一是:pnp、node-modules。

    【讨论】:

      【解决方案2】:

      我为此找到的解决方案是 Yarn 在您的根 package.json 文件中的 nohoist 选项。

      默认情况下,Yarn 将依赖项提升到根目录,以便它们可以在您的包之间共享。不幸的是,这不适用于 Firebase。这意味着您需要告诉 Yarn 不要提升 Firebase 函数使用的依赖项。

      nohoist 的文档不太理想,但这里有一篇关于它的官方博客文章: https://yarnpkg.com/blog/2018/02/15/nohoist/

      你可能想要这样的东西:

      {
        "workspaces": {
          "packages": [
            "packages/*"
          ],
          "nohoist": [
            "functions/core",
            "functions/common",
            "functions/**"
          ]
        }
      }
      

      请记住,这使用了每个工作区包的 package.json 文件中使用的 name 字段。所以在这个例子中,假设functions 目录有一个package.json 与“功能”,因为它是name

      functions/** 告诉 yarn 不要提升packages/functions/package.json 中指定的任何依赖项。不过,这不适用于您的共享纱线包,因此需要单独指定 functions/corefunctions/common

      您还需要将工作空间作为依赖项包含在您的 functions 项目中,因此请将它们添加到您的 package.json

      {
        "name": "functions",
        "dependencies": {
          "core": "*",
          "common": "*",
        }
      }
      

      添加完所有内容后,您应该删除您的packages/functions/node_modules 目录并运行yarn install。完成此操作后,您应该会看到 packages/functions/node_modules 中包含的所有依赖项(不是符号链接)。

      【讨论】:

      • 我尝试了这种方法,但无法部署这些功能。 firebase 进程无法安装依赖项(因为它们是本地的)
      • @ThiagoNascimento 嗯。我前一阵子这样做了,忘了发布这个答案。我可能忘记了这个过程中的另一个步骤。我会看看。谢谢你让我知道。如果我发现了什么,我会更新它。
      • 我创建了一个存储库来演示该技术的使用,但是在将这些功能部署到 Firebase 时我似乎遇到了问题,即使 Web(托管)方面工作正常。任何帮助将不胜感激 - 我已将错误添加到自述文件github.com/cjmyles/firebase-monorepo
      • 我也无法让它与云功能一起使用。虽然 node_modules 包含共享核心包,但云功能的部署不使用 node_modules。因此,我只能创建共享依赖项的打包版本,然后更新 packages.json。
      • 我无法成功运行yarn install,即使在nohoist 中指定了functions/**,base64 和node-waf 等一些软件包似乎也无法运行
      【解决方案3】:

      我不确定我是否完全理解这个问题,但根据我从您的问题和使用它的经验中了解到的任何信息,我可以在纱线工作区上给您两美分。

      Yarn 工作区将所有依赖项整合到项目根目录中的 node_modules 以及单个 package-lock.json 中,以减少冲突并使 yarn 能够优化安装过程为您提供更快的yarn install。而且它还有一个好处是,通过一次yarn install可以安装工作空间下所有包的依赖。

      编辑:我认为由于某种原因 yarn link 没有被调用,而是只有 yarn install 正在运行,它将搜索 npm 注册表并抛出评论中提到的错误,因为它可以'在 npm 注册表上找不到提到的包。因此,对于解决方案,请尝试在 firebase 的 package.json 中创建一个条目,例如

      "dependencies": {
        "a": "file:../dependency-package-name/",
      }
      

      【讨论】:

      • 我知道纱线工作区是如何工作的,我目前正在项目中使用。我遇到的问题是,当从同一个项目中导入另一个本地包时,yarn 负责对其进行符号链接,因此它实际上不会指向 node_modules,而是从本地包中导入。这就是问题所在,firebase 函数似乎不适用于不在 node_modules 中的符号链接包
      • 现在这个问题对我来说更清楚了。是的纱线符号链接以打包在同一工作区中。但是你到底面临什么问题。它应该像 npm 安装包一样工作。
      • 在部署到 firebase 函数时,我收到一个错误,指出找不到某些 X 包(本地)
      • 在项目中,我猜 yarn.lock 文件在那里,因为如果不是,谷歌云使用 npm 安装,这可能无法进行我猜的符号链接。
      • 是的,yarn.lock 在那里。谷歌云甚至支持纱线吗?也许这就是重点
      猜你喜欢
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2022-08-02
      相关资源
      最近更新 更多