您如何在一个仓库中与其他团队共享本地npm软件包?

时间:2019-04-10 18:02:48

标签: javascript node.js npm npm-install npm-scripts

场景

请考虑以下文件夹结构:

/my-service
  /src
  /bin
  /other-package
    /src
    package.json
  package.json

有2个npm软件包:一个用于my-service,一个用于other-package

my-service取决于other-package

my-service由团队A拥有,other-package由团队B拥有。

B发生变化时,请紧记团队my-service仍需要部署other-package。这就是我们考虑共享存储库的原因。

问题

您如何构建这种依赖关系,以使两个团队的开发人员经验都合理?

理想情况下,团队B只需要安装和构建other-package,就可以在该目录中完成他们需要做的所有事情。

同样,A团队应该能够使用other-package的最新版本,而在本地开发中的摩擦却最小。

选项

我目前正在考虑两种解决方案,但是不知道是否还有更好的选择。

本地文件依赖性

在此选项中,my-service的{​​{1}}如下所示:

package.json

本地tarball依赖项

在此选项中, "dependencies": { "other-package": "./other-package" }, "scripts": { "build": "npm run build:other-package && npm run build", "build:other-package": "cd other-package && npm i && npm run build && cd .." } 的{​​{1}}如下所示:

my-service

在这种情况下,团队package.json需要负责在新版本准备就绪时在 "dependencies": { "other-package": "./other-package/other-package-0.0.1.tgz" } 目录中运行B,并更新{{1 }},并将其提交给git。

2 个答案:

答案 0 :(得分:1)

将这两个软件包放入单独的存储库中,并在第一个软件包的package.json文件中将依赖关系放到第二个软件包的git存储库中。如下所示:

"dependencies": {
  "my-other-package": "git://github.com/user/project.git#commit-ish"
}

有关可用语法选项的详细信息,请参见npm documentation

通过这种方式,两个团队都可以独立且彼此独立地处理其软件包。同时,可以通过其git url引用该包,甚至可以通过提供其commit-ish来固定特定的分支,标签或提交。

如果您使用GitHub管理git存储库,还可以使用快捷方式语法:

"dependencies": {
  "my-other-package": "user/project#commit-ish"
}

这也适用于私有存储库,但仅适用于GitHub。如果使用其他git托管解决方案,则需要使用上述语法。

由于您提到从属团队希望使用最新版本而不会产生太多摩擦,因此您可能只想使用诸如#master之类的内容作为承诺。然后,在每个npm install上,您将获得提交到master分支的最新版本。

请注意,这将导致无法复制的构建,因为您无法确定地预测将要安装的内容。根据我的个人经验,我宁愿建议将您的依赖项固定到特定的提交。尽管这需要进行更多维护工作,但可以实现可重复且可预测的安装,恕我直言,这很有价值,但YMMV值得。

此方法的一大优势是,两个团队不必在发布或诸如此类的事情上互相关心,因为您可以依赖外部的软件包,而无需团队管理软件包有人在使用它。

如果出于某种原因绝对必须将 HAS 设为一个存储库,并且您不能使用我描述的方法,那么您可能会对术语“ monorepo”感兴趣。基本上,这是为多个软件包提供一个(单一)存储库的概念。 Lerna是管理此类Monorepo的一种工具,您可能需要对其进行仔细研究。

答案 1 :(得分:-2)

  那些长期分裂的人应当团结起来;那些长期团结的人应该分开。

最近,我帮助我的团队过渡到monorepo,将10多个存储库合并为一个。 Monorepo有一些缺点,当它变得很大时(例如Google的),它会给版本控制功能带来压力。另一方面,它有助于代码共享,重用构建脚本,ci流,git历史记录和文件上的批处理op等。

典型的monorepo方法平等对待子项目。

/monorepo
  /node_modules <-- shared top level node_modules
  /packages
    /my-service
    /other-package

如果不是出于特殊原因,我建议您将两个软件包都保留为兄弟姐妹,而不是父子。

完成其中任何一个(例如说其他软件包)的构建后,您将其目录符号链接到顶级node_modules目录中。

# in /monorepo
ln -s packages/other-package node_modules

如果您愿意尝试使用lerna.js之类的工具,那么它可以帮助您完成琐事。

现在您可以像平常一样指定my-service/package.json

  "dependencies": {
    "other-package": "latest"
  }