Monorepo

monolithic repository 单体式仓库,与之对应的是Multirepo(Multiple repository)

Multirepo是比较传统的做法,即每个package都单独使用一个仓库来进行管理

Monorepo是吧所有相关的package都放到同一个仓库进行管理,每个package独立发布。如React、Babel、Vue

MultiRepo方式允许多元化发展(各项目可以有自己的构建工具、依赖管理策略、单元测试方法)。虽然拆分子仓库、拆分子npm包是进行项目隔离的天然方案,但当仓库内容出现关联时,调试需要npm link。调试方式比较低效。

MonoRepo方式则希望集中管理,减少项目间的差异带来的沟通成本。将业务代码聚合,开发者只需要关心业务代码,可以直接跨业务复用而不用关心复用方式,调试时所有的代码都在源码中,非常高效。

Lerna

A tool for managing javascript projects with multiple packages.
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.

Lerna是一个管理多个npm模块的工具,优化维护多包的工作流,解决多个包相互依赖,且发布需要手动维护多个包的问题。

Lerna实践

1. 安装

npm i -g lerna             // 推荐全局安装

2.初始化

lerna init

初始化的目录结构如下图所示:

其中package.json 和lerna.json内容如下所示:

### package.json
{"name": "root","private": true,"devDependencies": {"lerna": "^4.0.0"}
}### lerna.json
{"packages": ["packages/*"],"version": "0.0.0"
}

3. 在monorepo项目下新增一个package

lerna create @demo/cli

分别给相应的package增加依赖模块

lerna add chalk                                           // 为所有的package增加chalk模块
lerna add semver --scope @demo/cli        // 仅为@demo/cli 增加semver模块

4. 发布

lerna publish

5.安装依赖包,并清理依赖包,扁平化依赖包

在维护整个项目时,需要为每个package安装依赖包,但如果项目下多个package引用了相同的依赖包,在每个package的node_modules下都安装一遍该依赖包,会导致同一个依赖包安装多次,显得冗余,且每个package都要维护node_modules, 结构很不清爽。故可以使用lerna bootstrap --hoist命令将每个package下的依赖包提升到工程根目录,来降低安装及管理成本。

lerna bootstrap --hoist
或lerna.json中配置{"packages": ["packages/*"],"version": "0.0.0","command": {"bootstrap": {"hoist": true}},
}

配置好后,对于之前依赖包已经被安装到各个package的node_modules下的情况,我们只需清理一下安装的依赖即可:

lerna clean

Rush.js

rush.js微软出品,专门为monorepo打造的项目管理工具 rushjs.io

rush.js主要解决了两个重要问题: phantom dependencies和doppelgangers(幽灵依赖)

phantom dependencies

没有在package.json中指定安装,却可以在项目中被引用的依赖

如: 项目project-A中引用了component-b, 组件component-b内引用了库lib-a,项目project-A内引用lib-a能生效么?

在npm3.0后是可以的。因为npm原有的树形结构,造成了依赖冗余和路径过深。npm3后开始扁平化,把原来不统计的依赖变成了同级依赖。这样我们就可以在项目中直接引用到了。

phantom dependencies的问题

  • 版本依赖混乱
  • 依赖丢失
    常规解决思路:制定代码规范;使用代码检查工具来避免这种情况发生。

Doppelgangers

幽灵依赖:同一个依赖被安装多次,导致项目臃肿,打包变慢。

Rush.js的Symlink机制

Rush会将项目依赖全部都安装在repo更目录的common/temp下,然后提供symlink到各个项目中去引用。原本的项目中,依然会保持原有的node_modules结构

看一个例子:

Rush保证只会在项目的node_modules中保留package.json中声明过的依赖的symlink,这样就解决了phantom dependencies

rush会将所有的依赖都安装在一个地方,对于不同版本的同一个依赖,rush会同时安装所有的依赖版本,并提供symlink供项目使用,这样就解决了doppelgangers.

另外,rush会对依赖的版本(semver)进行智能判断,防止重复安装依赖包。例如,两个项目同时依赖了一个第三方库,第一个项目依赖的是^1.2.0。另一个依赖的版本号是1.5.0。rush安装依赖时,只会安装1.5.0.

Rush.js的简单使用

Rush.json

Rush build

Rush update

Rush change

Rush publish

Rush vs Lerna

Rush:

  • 规范性强,配置细分,各司其职
  • 消除phantom,可控性更强
  • 消除doppelgangers,减少依赖冗余更彻底
  • 可以实现更智能的版本选择
  • 支持npm/yarn/pnpm,其中pnpm是lerna不支持的
  • 对change log的更新支持更好,lerna则需要扩展

Lerna:

  • 当前使用最广,经过各大型项目检验
  • 配置简单,可扩展性好
  • 版本号管理有成熟的fixed/independent两种模式,Rush的version Policy目前还是实验性功能

Monorepo + lerna rush.js相关推荐

  1. 你所需要了解的关于 Monorepo 的一切

    你所需要了解的关于 Monorepo 的一切 Monorepo 1. 前言 2. Monorepo 2.1 它是什么? 2.2 为什么要使用 Monorepo 2.2.1 Polyrepo 2.2.2 ...

  2. Lerna 运行流程剖析

    大家好,我是若川.持续组织了6个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...

  3. monorepo工作流基础之changesets打开与进阶(Speeches)

    文章目录 背景 先置理论 聊聊工作流 workflow 一致性问题 开源项目的工作流解法 github bot github actions 实践赋能 安装 changesets 配置 changes ...

  4. 8102年底如何开发和维护一个npm项目

    开发流程 初始化 首先在npm官网进行注册登录 运行npm init,可以通过命令行进行一些初始化的设置,如果想快速进行设置,可以运行npm init -y,会在项目的根目录生成一个package.j ...

  5. 哔哩哔哩 Web 首页重构——回首2021

    本期作者 刘磊 高能链开放平台资深前端开发工程师 01 前言 在 2021 年时我们通过数据分析发现:在电脑端有越来越多用户的电脑屏幕切换成了大屏,现有 B 站的网页设计风格已经难以在宽屏设备上高效率 ...

  6. 如何构建一个在线绘图工具:Feakin 是如何设计与构建的?

    高中,读过几本 3D 图形编程相关的书.怎么说呢,自那以后,图形学相关的东西,都不在我的兴趣范围里了.直到最近,我重新燃起了一点兴趣: 架构治理工具 ArchGuard 依赖于「图即代码」,用于生成架 ...

  7. 第 5 届 FEDAY 前端大会的完整 PPT 内容已出炉-站在大牛的肩膀上学习

    前言 有一种快速学习的方法是:站在大牛的肩膀上学习. 即使快能为祖国母亲庆生了,但也阻挡不住大家博已广学的心. 一年一度的第 5 届 FEDAY (前端大会) 圆满结束,来自全球.有极丰富经验和技能的 ...

  8. 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践

    对于维护过多个package的同学来说,都会遇到一个选择题,这些package是放在一个仓库里维护还是放在多个仓库里单独维护,本文通过一个示例讲述了如何基于Lerna管理多个package,并和其它工 ...

  9. 现代前端工程化-基于 Monorepo 的 lerna 模块(从原理到实战)

    本文你能学到什么? 看完本文后希望可以检查一下图中的内容是否都掌握了,文中的例子最好实际操作一下,下面开始正文. 本文是前端工程化系列中的一篇,回不断更新,下篇更新内容可看文末的下期预告!宗旨:工程化 ...

  10. 使用lerna构建monorepo

    使用lerna构建monorepo monorepo是什么? monorepo就是在一个git repository里面管理多个packages或者项目 在实际开发使用中,在哪些场景下可能你会想要使用 ...

最新文章

  1. 今天来说一下我的SAMC
  2. IOS使用通知回调方法
  3. python自动化功能测试_python、selenium自动化功能测试
  4. 牛客练习赛89E-牛牛小数点【数论】
  5. Oracle 20c 新特性:表空间缺省加密算法 TABLESPACE_ENCRYPTION_DEFAULT_ALGORITHM
  6. QT5::总结篇 QWidget
  7. 旅游网站进行邮件订阅的七大步骤讲解
  8. 博弈指什么棋_格局:什么是格局?(胜读十年书)
  9. Extjs ComboBox常用的配置
  10. html超链接下划线改虚线_怎么把下划线变成虚线
  11. 苹果和华为如何隔空传照片
  12. html的图片动态效果,用CSS3实现图片动态效果
  13. 多目标优化系列(六)SPEA
  14. 手机网站(wap)广告展示一般都有哪些表现形式?
  15. NIO核心设计与原理
  16. c语言编程序按下列公式计算e的值,编写程序,利用公式 ,求出e的近似值
  17. 清理docker的overlay2日志释放磁盘空间
  18. random.RandomState()用处
  19. G - Ugly Numbers
  20. [Outlook] outlook如何实现自动CC和BCC邮件发送

热门文章

  1. 时区相关-这一篇全了解
  2. 做了这么多年的技术,你有写过博客吗?
  3. python之生成器函数
  4. 洛谷2672 推销员
  5. 洛谷 P2672 推销员 解题报告
  6. Cocoa Touch框架浅析
  7. 清理c盘爆满告急,C盘清理
  8. 地理总结(二)--我国华北华南华中等地区的划分
  9. 数据库COUNT(*)、COUNT(字段)和COUNT(1)的异同
  10. ANSA二次开发实战——车身弯扭刚度计算文件自动生成(1)