原文链接: https://codeburst.io/monorepos-by-example-part-1-3a883b49047e
让我们通过实例来探索 monorepos.
首先,关于 monorepo:
Definitions vary, but we define a monorepo as follows:
The repository contains more than one logical project (e.g. an iOS client and a web-application)
These projects are most likely unrelated, loosely connected or can be connected by other means (e.g via dependency management tools)
The repository is large in many ways:
Atlassian — Monorepos in Git.
其次,我也赞同这些反对 monorepo 项目的论据:
Monorepos in the Wild - Markus Oberlehner - Medium
接下来,我们将通过示例来讨论几个实际的问题,使用 lerna 来管理一个 monorepo 项目( javascript 项目 ) .
这个系列的最终 monorepo 在这里,点击查看.
在我们处理 monprepo项目 ( 特别是lerna所管理的monorepo项目 ) 的问题时, 我们需要先建立一个 lerna monorepo 项目, 幸运的是这十分的简单.
首先, 全局安装lerna:
sudo npm install --global lerna
注意: 本教程使用的是nodejs v8.9.4 与 Lerna v2.9.0
创建一个新的文件夹, 并在其中运行一下命令将其转换为一个Lerna monorepo 项目.
git init
lerna init
最后生成的文件夹结构应该是这个样子的:
现在,我们已经有了一个 Lerna monorepo 项目, 就可以开始尝试创建 package 了. 在部署到 npm 仓库中时, 每个package 将会是以单独的一个 npm package 的形式存在的. 通俗来说就是, package 允许更松散的耦合以及独立的依赖管理( 稍后会做介绍 ).
我们可以通过在 packages 文件夹下新建一个文件的形式来创建一个 package, 并在对应目录下执行以下命令 :
npm init -y
这时,项目文件夹结构会类似这样:
假设我们三个项目都依赖于 npm 包 sillyname@0.0.3 ( 特定版本 ), 我们可以运行命令: ( Lerna 命令可以在项目下的任何文件夹中执行 )
lerna add sillyname@0.0.3
然后, 项目的目录结构将会是类似于这样的:
显然:
对此, Lerna 也有着解决方法; 使用 hoist 参数
lerna add sillyname@0.0.3 --hoist
最后的项目文件夹结构将会是这样的 (截图中并没有展示庞大的 node_modules 文件夹) :
显然:
假如我们只想为 grocery 这个 package 升级 sillyname 的版本, 我们可以执行以下命令:
lerna add sillyname@0.1.0 --scope=grocery
然后, 项目的目录结构将会是类似于这样的:
显然:
现在, 加入我们希望 grocery 去依赖 apple 和 banana, 我们可以执行以下命令:
lerna add apple banana --scope=grocery
最后的项目文件夹结构将会是这样的
显然:
现在, 我们已经设置好了相关依赖, 可以开始编写一些代码了.
packages/apple/index.js
const sillyname = require('sillyname');
module.exports = `apple and ${sillyname()}`;
packages/banana/index.js
const sillyname = require('sillyname');
module.exports = `banana and ${sillyname()}`;
packages/apple/grocery.js
const sillyname = require('sillyname');
const apple = require('apple');
const banana = require('banana');
console.log(`grocery and ${sillyname()}`);
console.log(apple);
console.log(banana);
然后在 grocery 的目录下运行一下命令:
node index.js
最后的输出会是这样的:
grocery and Linenhiss Butterfly
apple and Trailspeaker Scribe
banana and Translucentpuma Kangaroo
完成编码后, 我们添加以下文件, 因为我们不希望将 node_modules 文件夹存储在源代码管理中.
.gitignore
**/node_modules
然后将所有的文件提交到 git 仓库之中.
现在, 假如团队的另一名成员要加入开发. 首先, 他需要全局安装 Lerna.
sudo npm install --global lerna
然后, 他需要克隆仓库, 然后运行对应的名来安装所有依赖 ( 包括符号链接 ):
lerna bootstrap --hoist
现在, 这么成员就可以开始编码了. 遵循他们自己的工作流模式 (创建新分支等等).
在下一篇文章Monorepos By Example:Part 2 ( 未翻译 )中,我们将继续探讨一些更实际的问题。