1,首先举个例子,比如github上的react-router项目,目录结构是这样的:
打开packages文件夹里面结构是这样的:
以上可以发现,react-router的packages包中包含了许多其他的插件,因为这几个插件互相依赖,而且用到了共同的npm包,如果把他们分别放到一个项目里,管理起来会很麻烦,并且需要重复下载很多次相同的npm依赖,所以干脆放到同一个项目里。这个理念就是monorepo,所以monorepo只是一个管理项目的方式,是一个思想,不是工具。
2,那怎么实现这个思想呢,就是比如怎么做到,这几个项目都用到同一个npm依赖的时候,只下载一次npm包就能让所有的项目共同拥有?分析react-router的项目结构,我们可以发现,这个react-router的项目结构 是这样的:
react-router
——packages
——package1
——package.json
——package2
——package.json
——package3
——package.json
——lerna.json
——package.json
里面有个lerna.json,lerna就是用来实现monorepo的工具。
3,如何使用lerna呢?
首先全局安装lerna: npm i -g lerna
创建一个项目文件夹并生成.git文件:git init lerna-test
初始化lerna: lerna init
在生成的packages文件夹中添加两个包:mkdir package0、mkdir package1
在package0中创建package.json: npm init -y
在package0中新建index.js文件:在其中require("package1")
在package0中修改package.json:
"dependencies": {
"package1": "^1.0.0"
}
为packages目录下所有包安装它们的依赖,为内部互相依赖的package建立symlink,对所有的package执行npm prepublish:lerna bootstrap
使用lerna将公共的依赖下载到外部,非公共的依赖下载到包本身的配置,然后执行lerna bootstrap
//lerna.json
"packages": [
"packages/*"
],
"command": {
"bootstrap": {
"hoist": true
}
},
4,除了lerna,还可以使用yarn去管理?
lerna 在安装依赖时提供了--hoist选项,相同的依赖,会「提升」到 repo 根目录下安装,但是前提是,lerna 直接以字符串对比 dependency 的版本号,完全相同才提升,semver 约定在这并不起作用。
使用yarn:详情查看yarn
在项目根目录下的package.json中添加:
{
"private": true,
"workspaces": ["package0", "package1"]
}
在项目根目录下的lerna.json中添加:
{
"packages": [
"packages/*"
],
"useWorkspaces": true,
"npmClient": "yarn",
// "command": {
// "bootstrap": {
// "hoist": true
// }
// },
}
5,lerna和yarn可以同时使用,并不是二者只能选其一。
lerna和yarn workspace的区别:
hoist: 提取公共的依赖到根目录的node_moduels
,可以自定义指定。其余依赖安装的package/node_modeles
中,可执行文件必须安装在package/node_modeles
。
workspaces: 所有依赖全部在跟目录的node_moduels
,除了可执行文件