Node.js 在monorepo中的多个项目之间共享模块

Node.js 在monorepo中的多个项目之间共享模块,node.js,npm,Node.js,Npm,我有一个带有几个项目的小型monorepo(它们共享相同的数据存储,因此在monorepo中一起进行开发和测试更容易)。每个项目都位于自己的文件夹中,并带有自己的package.json。每个项目都应该独立部署(独立于其他项目) 我想在项目之间分享一些代码。我希望保持它们的相对独立性,因此我不希望在根repo文件夹中创建“构建”步骤,也不希望每个项目都有自己的构建步骤。理想情况下,每个项目的部署将继续在项目文件夹中完成,而不需要了解其他项目 我知道我可以在回购协议中创建一个npm模块,并从每个项

我有一个带有几个项目的小型monorepo(它们共享相同的数据存储,因此在monorepo中一起进行开发和测试更容易)。每个项目都位于自己的文件夹中,并带有自己的package.json。每个项目都应该独立部署(独立于其他项目)

我想在项目之间分享一些代码。我希望保持它们的相对独立性,因此我不希望在根repo文件夹中创建“构建”步骤,也不希望每个项目都有自己的构建步骤。理想情况下,每个项目的部署将继续在项目文件夹中完成,而不需要了解其他项目

我知道我可以在回购协议中创建一个npm模块,并从每个项目中链接到它。这是我倾向于的解决方案。但我想知道是否有人有更好的主意

下面是一个目录结构的示例:

/package.json
/docker-compose.yml
/project-1/package.json
/project-2/package.json
/package.json
/docker-compose.yml
/project-1/package.json
/project-2/package.json
/project-shared/package.json

如果我使用
npm链接
解决方案,我会添加类似于
项目共享
文件夹的内容,并从
project-1
project-2
链接到它,这就是我目前使用的npm链接解决方案。这似乎是一个不错的解决方案,所以我想我应该把它作为一个答案。我还没有为这个项目实现部署,所以我不知道部署是否能很好地处理这个问题。我希望它将部署链接模块以及其他所有内容

项目目录结构如下所示:

/package.json
/docker-compose.yml
/project-1/package.json
/project-2/package.json
/package.json
/docker-compose.yml
/project-1/package.json
/project-2/package.json
/project-shared/package.json
在每个项目的package.json(
project-1
project-2
)中,我添加了以下安装后脚本:

“脚本”:{
“安装后”:“npm链接../project共享”
},
因此,链接将在项目的正常设置期间创建

注意:由于某些原因,使用
preinstall
脚本无法执行此操作(虽然链接看起来已运行,但不会创建链接)<代码>后安装工作正常

我不太清楚共享模块的依赖项安装是如何工作的(例如,当项目链接到共享模块时,是否会安装共享模块的依赖项,或者我是否必须独立安装它们)

我遇到的一个问题是Docker Compose不能很好地处理链接包(symlinked文件夹不会指向容器中的正确位置)。我通过在node_modules文件夹中的符号链接上挂载共享文件夹修复了这个问题。例如,对于
project-1

卷:
-“/project-1/:/home/node/app:ro”
-“/project shared/:/home/node/app/node_模块/project shared:ro”
编辑:2020年9月4日

我想提醒大家,我已经在生产中使用了一段时间,而且效果很好。我在dev中注意到的一个问题是,共享库安装在Docker容器中,当您从主机
npm安装时,它将运行
postinstall
并将共享库文件夹符号链接。这是意料之中的,除了在Docker中,它会弄乱你的坐骑。我找到的解决方案是停止Docker,删除链接,重新创建文件夹,然后再次启动Docker。更好的解决方案可能是将
postinstall
脚本替换为以下内容:

"postinstall": "test -d node_modules/project-shared || npm link ../project-shared"

这将仅在文件夹不存在时链接该文件夹。我只测试了一点,所以我不确定是否遗漏了任何奇怪的边缘情况。

您是否首先需要在
project shared
中运行
npm link
以使其可用于链接?在本地,这可能不是一个问题,因为它只需要执行一次,但我想知道如何为其他创建repo新克隆的开发人员最好地解决它。太糟糕了,链接状态无法更明确地持久化。@bluenote10不,我认为只有当您希望它作为一种“全局”包,这样您才能像对待普通npm包一样对待它,而不提供路径。如果您只提供一个到
npm link
的路径,它将链接任何存在的内容。