Monorepo——大型前端项目的代码管理方式

栏目: 编程工具 · 发布时间: 6年前

内容简介:最近我接手了一个项目,代码量比较大、有点复杂。仓库 clone 下来代码有 50+ MB,npm install 安装完体积飚到了近 2GB …… 熟悉了一下,这个项目比较复杂,采用了 monorepo 的方式进行代码的管理。折腾几天后,对 monorepo 也有个大概的了解……Monorepo 是管理项目代码的一个方式,指在一个项目仓库 (repo) 中管理多个模块/包 (package),不同于常见的每个模块建一个 repo。目前有不少大型开源项目采用了这种方式,如

最近我接手了一个项目,代码量比较大、有点复杂。仓库 clone 下来代码有 50+ MB,npm install 安装完体积飚到了近 2GB …… 熟悉了一下,这个项目比较复杂,采用了 monorepo 的方式进行代码的管理。折腾几天后,对 monorepo 也有个大概的了解……

Monorepo

Monorepo 是管理项目代码的一个方式,指在一个项目仓库 (repo) 中管理多个模块/包 (package),不同于常见的每个模块建一个 repo。

目前有不少大型开源项目采用了这种方式,如 Babel

How is the repo structured?

还有 create-react-app , react-router 等。可以看到这些项目的第一级目录的内容以脚手架为主,主要内容都在 packages 目录中、分多个 package 进行管理。

├── packages
|   ├── pkg1
|   |   ├── package.json
|   ├── pkg2
|   |   ├── package.json
├── package.json

monorepo 最主要的好处是 统一的工作流Code Sharing 。比如我想看一个 pacakge 的代码、了解某段逻辑,不需要找它的 repo,直接就在当前 repo;当某个需求要修改多个 pacakge 时,不需要分别到各自的 repo 进行修改、测试、发版或者 npm link ,直接在当前 repo 修改,统一测试、统一发版。 只要搭建一套脚手架,就能管理(构建、测试、发布)多个 package

不好的方面则主要是 repo 的体积较大。特别是,因为各个 package 理论上都是独立的,所以每个 package 都维护着自己的 dependencies,而很大的可能性,package 之间有不少相同的依赖,而这就可能使 install 时出现重复安装,使本来就很大的 node_modues 继续膨胀(我称这为「依赖爆炸」...)。

基于对以上的理解,我认为当项目到一定的复杂度,需要且可以划分模块、但模块间联系紧密的,比较适合用 monorepo 组织代码。

目前最常见的 monorepo 解决方案是 Lernayarnworkspaces 特性。其中,lerna 是一个独立的包,其官网的介绍是:

a tool that optimizes the workflow around managing multi-package repositories with git and npm.

上面提到的 Babel, create-react-app 等都是用 lerna 进行管理的。在项目 repo 中以 lerna.json 声明 packages 后,lerna 为项目提供了统一的 repo 依赖安装 ( lerna bootstrap ),统一的执行 package scripts ( lerna run ),统一的 npm 发版 ( lerna publish ) 等特性。对于「依赖爆炸」的问题,lerna 在安装依赖时提供了 --hoist 选项,相同的依赖,会「提升」到 repo 根目录下安装,但……太鸡肋了,lerna 直接以字符串对比 dependency 的版本号,完全相同才提升,semver 约定在这并不起作用。

具体的使用方法移步 Lerna 官网: https://lerna.js.org

而使用 yarn 作为包管理器的同学,可以在 package.json 中以 workspaces 字段声明 packages,yarn 就会以 monorepo 的方式管理 packages。相比 lerna,yarn 突出的是对依赖的管理,包括 packages 的相互依赖、packages 对第三方的依赖,yarn 会以 semver 约定来分析 dependencies 的版本,安装依赖时更快、占用体积更小;但欠缺了「统一工作流」方面的实现。

yarn 官网对 workspace 的详细说明: Workspaces | Yarn

lerna 和 yarn-workspace 并不是只能选其一,大多 monorepo 即会使用 lerna 又会在 package.json 声明 workspaces 。这样的话,无论你的包管理器是 npm 还是 yarn,都能发挥 monorepo 的优势;要是包管理是 yarn ,lerna 就会把依赖安装交给 yarn 处理。

再说回我那项目呢,安装依赖后体积实在是大,折腾了两天想要优化一下,但目前大量脚本严重依赖 npm,我……

Monorepo——大型前端项目的代码管理方式

还是后面考虑慢慢迁移到 yarn 吧。

Reference

Others

git-submodule

通过 Git 子模块,可以在当前 repo 中包含其它 repos、作为当前 repo 的子目录使用,同时能够保持 repos 之间的独立。

# 在当前 repo 添加一个子模块
git submodule add git@github.com:xxx/xxx.git path/to/xxx

可以在 .gitmodule 文件中看到当前 repo 有哪些 submodule,分别的 name , branch 等。

# clone 含有 submodule 的 repo 后:
# 初始化 git submodule 信息
git submodule init
# 更新 submodule,相当于 git pull 吧
git submodule update

修改子模块文件后,在当前 repo 执行 git status 只会看到有模块的 changes,而不是具体子模块文件:

diff --git a/path/to/submodule b/path/to/submodule
--- a/path/to/submodule
+++ b/path/to/submodule
@@ -1 +1 @@
-Subproject commit xxxxxxx
+Subproject commit xxxxxxx-dirty

dirty 表示子模块的修改还不是 commit。如果子模块的修改 commit 后,这个改动就会是具体的 commit id。

子模块的其它 commit , pull 等各操作,还是到其目录下,按普通 repo 操作即可。

Reference

git-bisect

git 有一个以二分法帮助定位问题的命令—— bisect

# 开始二分查找问题
git bisect start
# 标记当前有问题
git bisect bad
# 标记哪个 commit 或 tag 时是没问题的
git bisect good v1.0.0

# 此时 git 会 checkout 两个点之间的某个 commit,
# 如果此时还是有问题:
git bisect bad
# 如果此时没有问题:
git bisect good
# 接着 git 会 checkout 下一个「有问题」和「没问题」之间的 commit

# 直到定位到问题,git 会提示:xxxxxxx is first bad commit

Reference

欢迎关注我的订阅号——「车迷与码农」,不定期分享关于前端、汽车和有趣的事儿~

Monorepo——大型前端项目的代码管理方式


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Development with Rails 4

Agile Web Development with Rails 4

Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2013-10-11 / USD 43.95

Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details. Tens of thousands of deve......一起来看看 《Agile Web Development with Rails 4》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具