什么是javascript monorepo的正确方法

什么是javascript monorepo的正确方法,javascript,npm,webpack,lerna,monorepo,Javascript,Npm,Webpack,Lerna,Monorepo,我试图找出javascript monorepo的正确方法。想象一下包含包/库的monorepo: root - node_modules - packages + lib-a * node_modules + lib-b * node_modules 现在让我们假设lib-a和lib-b包都使用webpack作为构建工具 我看到两种方法 将wepback作为依赖项添加到根目录。在两个包中都包含“build”脚本:“bui

我试图找出javascript monorepo的正确方法。想象一下包含包/库的monorepo:

root
  - node_modules
  - packages
      + lib-a
          * node_modules
      + lib-b
          * node_modules
现在让我们假设
lib-a
lib-b
包都使用
webpack
作为构建工具

我看到两种方法

  • wepback
    作为依赖项添加到根目录。在两个包中都包含“build”脚本:
    “build”:“webpack-p--config webpack.config.js
    webpack.config.js
    可以包含root
    webpack.config.js
    。然后我可以使用类似于
    lerna
    的工具从根目录运行构建(这意味着可以识别
    webpack
    二进制文件。但是,由于
    webpack
    在特定软件包中不可用,我将无法运行构建。我可能会将构建脚本更改为类似于
    “build”:./../node\u modules/.bin/webpack-p--config webpack.config.js

  • 始终在每个包中包含
    webpack
    。这意味着
    build
    脚本将成功。这也意味着每个包将具有相同的依赖关系,我可能应该注意每个包使用相同的
    webpack
    版本


  • 基本上,我想说的是monorepo内部的包应该如何构造?如果发布了任何包,是否总是可以
    单独构建该包。

    我们当前的配置与您相同:

    root
      - node_modules
      - packages
          + lib-a
              * node_modules
          + lib-b
              * node_modules
    
    我们使用lerna处理我们的项目:

    您只需要在
    lerna.json

    {
      "lerna": "3.16.4",
      "packages": ["packages/*"],
      "version": "0.0.0",
      "npmClient": "yarn",
      "useWorkspaces": true
    }
    
    然后在
    package.json
    脚本中,您可以使用以下行:

    "build": "lerna run build",
    
    这将基本上在所有包中运行一个构建。因此,只要每个包中的构建脚本都安装了正确的参数和webpack,它就会自动运行webpack构建

    之后,您只需在指定的包中处理工作。

    您的方法#2是正确的。您单独处理每个包,因为它是一个独立的、自包含的包

    monorepo的优势不在于通过目录结构共享文件,而在于:

  • 使用平面结构将所有依赖项引导到单个
    节点\u模块
    ,有效地消除重复
  • 通过常规软件包
    导入
    /
    require()
    使您的软件包可供其他软件包使用,因为它们是外部依赖项。而且,由于指向
    节点模块的符号链接,您的“依赖项”软件包始终包含最新内容,而不会发布
  • 在您的所有包中强制执行一致的、始终是最新的依赖关系结构。正如您所说的“这也意味着每个包将具有相同的依赖关系”
  • 使用自动化工具,只需一个命令即可在所有包上执行不同的维护任务(如构建、发布)

  • 我知道一开始并不容易,但当你深入研究Lerna文档时,它变得更加清晰了。除了Lerna之外,我建议你阅读Lerna以及诸如和之类的单独命令。

    我们的mono repo的工作方式是,每个包都有自己的节点模块,但你只能安装你和你感兴趣的模块。我们en在根目录下有一个命令构建,它基本上在所有包中执行构建,因此您将构建的责任放在“根”包上,并从那里运行构建命令。这似乎是正确的方法。我正在考虑对其余命令也这样做(例如测试、清理等)。你应该研究一下lerna。它有一些工具可以帮助你管理monorepo,还可以自动完成某些任务,比如链接monorepo中的包。我使用lerna来制作monorepo,它工作得很好。我认为将这个问题的标题改为“javascript monorepo的正确方法是什么”是有意义的。这将有助于其他人在通过Stackoverflow/Google搜索时找到此问题/答案。我在这里支持所有内容。每个包都应该能够自行构建和测试自己。我建议使用Thread Workspace+lerna,但这不是必需的。我们创建了根级别的tsconfig和jest config,它们由各个包导入/扩展。我们还让root负责所有包的linting,
    husky
    负责预提交钩子,
    commitizen
    负责一致提交消息。