Setup
我有一个具有以下文件结构的单存储库设置:
├── functions
│ ├── src
│ └── package.json
├── shared
| ├── dist
| ├── src
| └── package.json
├── frontend
| └── ...
└── firebase.json
方法 1(失败)
./shared
持有在./backend
和./frontend
之间共享的TypeScript类。理想情况下,我想使用符号链接从functions/package.json
引用共享库,以避免每次更改共享代码(大多数功能所在的位置)后都必须重新安装。
但是,这不起作用(既不使用link:
,也不使用绝对file:
路径,也不使用相对file:
路径)
// functions/package.json
...
"dependencies": {
"shared": "file:/home/boern/Desktop/wd/monorepo/shared"
...
}
导致firebase deploy --only functions
时出错 (error Package "shared" refers to a non-existing file '"home/boern/Desktop/wd/monorepo/shared"'
)。库(尽管存在于./functions/node_modules/
中)未传输到服务器?
方法 2(失败)
此外,在firebase.json中设置"functions": {"ignore": []}
也无济于事。
方法4(有效,但缺少要求a)见目标)
唯一起作用的是 adevine 在 Github 上的提议:
// functions/package.json
...
"scripts": {
...
"preinstall": "if [ -d ../shared ]; then npm pack ../shared; fi"
},
"dependencies": {
"shared": "file:./bbshared-1.0.0.tgz"
...
}
目标
有人可以指出一种引用本地库的方法吗 a)./functions
在开发过程中始终使用最新版本,并且 b) 使用常用 Firebase CLI 进行部署是否成功(而不是,例如使用 firelink)?还是根本不支持?
为了回答您的问题,Firebase 工具部署命令/管道确实不支持 monorepos。
我开发了一个通用解决方案并写了一篇关于它的文章。下面是一个 摘录相关部分,但这里是完整的链接 品 如果您有兴趣。
火力基地的问题
部署到Firebase时,它希望上传一个文件夹,就像 传统的单包存储库,包含源文件 以及声明其外部依赖项的清单文件。 在其云部署管道中收到文件后,然后 检测包管理器并运行安装和生成。
在 monorepo 中,尤其是私有存储库中,您的 Firebase 代码 通常依赖于来自同一的一个或多个共享包 存储库,您不希望在任何地方发布它们。
一旦Firebase尝试在云中查找这些依赖项,它们就会 找不到,部署失败。
破解你的出路
使用捆绑器
为了解决这个问题,你可以尝试使用像Webpack这样的捆绑器来 将您的 Firebase 代码与共享包代码合并,然后 从正在 Package.json 清单中删除这些包 发送到Firebase,所以它甚至不知道这些包的存在。
不幸的是,这种策略很快就会成为问题......
如果共享包本身没有捆绑所有 其输出中的依赖关系,Firebase 不知道共享的内容 代码依赖于,因为您没有包含或安装这些 体现。
然后您可以尝试捆绑所有内容,但是如果您的共享包 取决于你的Firebase包也依赖于的东西,你现在有 运行内部捆绑副本的代码的一部分 依赖关系和另一部分使用来自 包管理器安装的不同位置。
另外,有些库真的不喜欢捆绑,在我的 体验包括 Firebase 和 Google 客户端库。你 会很快发现自己试图通过 捆绑器设置,以便使事情正常工作。
即使您设法完成了所有这些工作,您也可能 创建大型捆绑包,然后可能导致问题 云功能的冷启动时间。
不完全是一个可靠或可扩展的解决方案。
打包和链接本地依赖项
可以说,更优雅的方法包括打包本地 对压缩包的依赖(类似于包的方式 发布到 NPM),并将结果复制到之前的构建输出 在更改的清单文件中链接它们。
这可以很好地工作,因为它基本上类似于您的 如果这些软件包是从以下位置安装的,Firebase 代码将起作用 外部域。
无论您是手动执行此操作,还是编写 shell 脚本来处理 事情,对我来说仍然感觉很麻烦和脆弱,但我认为 如果您的本地依赖项很简单,这是一个可行的解决方法。
但是,一旦您分享,这种方法很快就会变得毛茸茸的 包取决于其他共享包,因为这样你就会有 有多个层次的东西需要打包和适应。
一个解决方案
在我之前,我花了很多时间尝试不同的解决方法 意识到一个方便的解决方案是什么样子的。最初,我是 去追求PNPM特有的东西,但在研究它时,我意识到 对其他包管理器的支持应该不是那么困难。
能够为以下方面贡献一些有用的东西感觉很好 社区,所以我创建了 隔离包。名称 是通用的,因为它不包含特定于 Firebase 的任何内容, 虽然我目前不知道隔离的任何其他用例 输出。
它采用与前面包装中描述的方法类似的方法 和链接依赖项,但以更复杂的方式进行。它 旨在处理不同的设置和包管理器和 IT 完全向用户隐藏复杂性。
它公开的隔离二进制文件可以简单地添加到Firebase中。 预部署钩子,差不多就是这样!
这也允许您从多个不同的 打包并保持配置位于同一位置,而不是乱扔垃圾 单存储库根目录。
对于绝大多数用例,它应该是零配置的,并且 旨在与所有包管理器兼容。
这是我使方法 4 起作用的解决方法:
rm -rf ./node_modules
yarn cache clean # THIS IS IMPORTANT
yarn install
从./functions
文件夹运行此命令