javascript monorepo 的正确方法是什么
What is a correct approach to a javascript monorepo
我正在尝试找出 javascript monorepo 的正确方法。想象一下包含包/库的 monorepo:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
现在假设 lib-a
和 lib-b
包都使用 webpack
作为它们的构建工具。
我看到两种方法
添加 wepback
作为对 root 的依赖。在两个包中包含 "build" 脚本:"build": "webpack -p --config webpack.config.js
。 webpack.config.js
可以包含根 webpack.config.js
。然后我可以使用 lerna
之类的工具从根目录 运行 构建(这意味着 webpack
二进制文件被识别。但是我将无法 运行 在特定包中构建因为 webpack
在那里不可用。我可能会将构建脚本更改为 "build": "../../node_modules/.bin/webpack -p --config webpack.config.js
始终在每个包中包含 webpack
。这意味着 build
脚本将会成功。这也意味着每个包都将具有相同的依赖关系,我应该注意每个包都使用相同的 webpack
版本。
基本上我的意思是应该如何构造 monorepo 中的包?如果发布了任何包,是否总是可以单独 build
该包。
我们现在的配置和你一样:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
我们使用lerna来处理我们的项目:https://github.com/lerna/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 的优势不在于通过目录结构共享文件,而在于:
- 将所有依赖项引导至具有扁平结构的单个
node_modules
,有效地消除重复项。
- 通过常规包
import
/require()
使您的包对其他包可用,因为它们是外部依赖项。而且,由于指向 node_modules
的符号链接,您的 "dependency" 包始终包含最新内容而无需发布。
- 在所有包中强制执行一致的、始终最新的依赖结构。正如你所说 "This also means that each package will have the same dependency".
- 使用单个命令对所有包执行不同维护任务(如构建、发布)的自动化工具。
我知道一开始并不容易,但是当你深入研究 Lerna 文档时,它会变得更加清晰。除了 Lerna main page I recommend reading about hoisting, FAQ and individual commands like bootstrap and publish.
我正在尝试找出 javascript monorepo 的正确方法。想象一下包含包/库的 monorepo:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
现在假设 lib-a
和 lib-b
包都使用 webpack
作为它们的构建工具。
我看到两种方法
添加
wepback
作为对 root 的依赖。在两个包中包含 "build" 脚本:"build": "webpack -p --config webpack.config.js
。webpack.config.js
可以包含根webpack.config.js
。然后我可以使用lerna
之类的工具从根目录 运行 构建(这意味着webpack
二进制文件被识别。但是我将无法 运行 在特定包中构建因为webpack
在那里不可用。我可能会将构建脚本更改为"build": "../../node_modules/.bin/webpack -p --config webpack.config.js
始终在每个包中包含
webpack
。这意味着build
脚本将会成功。这也意味着每个包都将具有相同的依赖关系,我应该注意每个包都使用相同的webpack
版本。
基本上我的意思是应该如何构造 monorepo 中的包?如果发布了任何包,是否总是可以单独 build
该包。
我们现在的配置和你一样:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
我们使用lerna来处理我们的项目:https://github.com/lerna/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 的优势不在于通过目录结构共享文件,而在于:
- 将所有依赖项引导至具有扁平结构的单个
node_modules
,有效地消除重复项。 - 通过常规包
import
/require()
使您的包对其他包可用,因为它们是外部依赖项。而且,由于指向node_modules
的符号链接,您的 "dependency" 包始终包含最新内容而无需发布。 - 在所有包中强制执行一致的、始终最新的依赖结构。正如你所说 "This also means that each package will have the same dependency".
- 使用单个命令对所有包执行不同维护任务(如构建、发布)的自动化工具。
我知道一开始并不容易,但是当你深入研究 Lerna 文档时,它会变得更加清晰。除了 Lerna main page I recommend reading about hoisting, FAQ and individual commands like bootstrap and publish.