【问题标题】:Share module between multiple projects in a monorepo在 monorepo 中的多个项目之间共享模块
【发布时间】:2020-02-01 06:38:36
【问题描述】:

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

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

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

以下是目录结构的示例:

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

如果我采用npm link 解决方案,我会添加类似project-shared 的文件夹,并从project-1project-2 链接到它。

【问题讨论】:

    标签: node.js npm


    【解决方案1】:

    这是我目前正在使用的 npm 链接解决方案。这似乎是一个不错的解决方案,所以我想我会把它作为答案发布。我还没有为这个项目实现部署的东西,所以我不知道部署在这个项目上的效果如何。我希望它将与其他所有内容一起部署链接模块。

    项目目录结构如下:

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

    在每个项目的 package.json(project-1project-2)中,我添加了这个 postinstall 脚本:

    "scripts": {
      "postinstall": "npm link ../project-shared"
    },
    

    因此链接将在项目的正常设置期间创建。

    注意:由于某种原因,这不能使用preinstall 脚本(不会创建链接,尽管它看起来像是在运行)。 postinstall 工作得很好。

    我不太确定共享模块的依赖项安装如何工作(例如,如果共享模块的依赖项将在项目链接到它时安装,或者我是否必须独立安装它们)。

    我遇到的一个问题是 Docker Compose 不能很好地处理链接包(符号链接文件夹不会指向容器内的正确位置)。我通过将共享文件夹安装在 node_modules 文件夹中的符号链接上来解决此问题。例如,对于project-1

    volumes:
      - "./project-1/:/home/node/app:ro"
      - "./project-shared/:/home/node/app/node_modules/project-shared:ro"
    

    编辑:2020 年 9 月 4 日

    想要说明我已经在生产中使用了一段时间并且效果很好。我在开发中注意到的一个问题是,共享库安装在 Docker 容器中时,当您从主机上 npm install 时,它将运行 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 的路径,它将链接那里的任何内容。
    猜你喜欢
    • 2019-11-05
    • 2013-01-21
    • 2018-12-31
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2021-08-05
    • 2017-05-15
    • 1970-01-01
    相关资源
    最近更新 更多