什么是javascript monorepo的正确方法
我试图找出javascript monorepo的正确方法。想象一下包含包/库的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
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
可以包含rootwebpack.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
负责一致提交消息。