需求:调研一下多个项目使用公共模块吧 ~

背景

需求方:有一个模块,需要应用到另外一个项目上,并且当这个公共模块更新的时候能自动地更新到对应的项目中。

刚开始拿到这个需求的时候,我脑子里面第一个想到的就是抽出一个公共的组件,打一个npm包,应该就可以了,至于更新嘛,这……怎么做到自动更新呢?于是开始了调研,阅读材料等,寻求看有没有符合要求的方案。

四种方案,怎么选择?

在查看材料的过程当中,找到了四种方案,分别是:MonoRepository手动 Copy PasteNPM dependencyGit Submodule、以及Bit,分别我们来分析一下。

手动 Copy Paste

额,这个方案我想,工作一两年的技术人员可以做,但是作为在职场打拼了6年的老手来说,这也太不符合我“工匠精神”了吧!这个方案肯定是不会用的,就简单说一下怎么做吧:就是把公共模块复制一份到相应的项目中,当有任何需求改动的时候,两边同时作相应的修改。

Bit

Open infrastructure for component-driven applications to speed and scale development.

使用 Bit 可以做到帮助团队跟踪组件的状态、版本等信息,实现代码的同步,快速迭代、快速发布的效果,如果是开源的项目我觉得是一个非常不错的工具。通过创建账号,Bit 平台帮助我们实时地跟踪组件的状态,这也是为什么不使用 Bit 的原因,组件里面很可能包含了业务强相关的模块,会涉及到敏感信息,那就不适合用第三方平台的账号来跟踪我们的组件。由于安全问题弃用。

Monorepo

A monorepo (“mono” meaning ‘single’ and “repo” being short for ‘repository’) is a software development strategy where code for many projects is stored in the same repository.

传统来讲,我们一般都会使用Multiple Repository。每一个项目都有自己的代码仓库,每个团队都有相应代码库的权限,比较方便管理账号权限等功能,并且每个项目的CI/CD也是独立的,比较好搭建。而MonoRepo则需要我们在一个单独的仓库里面管理不同的项目,CI/CD也需要额外的脚本实现。那么MonoRepo到底适合什么样的场景呢?

  • 当团队有很多个代码仓库的时候,比如几十个甚至一百多个,那么使用Multiple Repository显然太痛苦,这么多的代码仓库太难管理了。
  • 当一个项目有很多依赖,那么跟踪这些依赖的版本就称为一件非常棘手的事情。比如说多个项目有相同的依赖,当依赖发生版本变化的时候,我们有多少项目,就需要做多少重复的更新依赖的操作。

这个时候MonoRepo就上场了,而Lerna是MonoRepo非常棒的一个工具,Lerna可以很好地帮助我们管理项目与项目之间的关系,共享运行脚本,简化依赖之间的联系,提供了非常有用的命令。

下面是Lerna代码库的目录结构示例:

image

使用MonoRepo的企业和组织非常多,包括且不仅限于:Google、Facebook、Babel, React, Angular, Ember 和 Vue等等。

而对于我们来说,如果想要建立MonoRepo,则需要将现有的代码项目合并到MonoRepo里面去,而且再加上上面所提到的需要额外的脚本来做不同项目的构建和发布,在我运行lerna publish的时候,会同时为所有的项目创建tag,如果某个项目没有发生变化还是会有,这个导致在做发布管理的时候不大合适。

以上,MonoRepo也被pass掉了。

Meta Repo

Meta Repo是基于Multiple Repository的,它解决的是多个代码仓库不好管理的问题,比如可以一个命令就clone很多个代码仓库;一条命令安装所有代码仓库的依赖,就不需要每个项目重复地做同样一件事情;也能够一个Git的提交给应用到所有的项目中。依然能保证不同项目的权限管理。Meta其实更像是一个工具,一个插件,帮助我们自动地做了很多事情。

而对于这篇文章的主题,共享公共模块,关系不是很大,所以这个方案是没有考虑。

Git Submodule

Git Submodule我在以前的项目中使用过的,当时是用了单独的repository来存储所欲的icons,这样的话我们不同的项目就可以从一个代码仓库里面去取icon,而不需要每一个项目都添加一遍。

类似地,公共模块的代码仓库也是一个独立的repository,有了任何的版本更新会打包成浏览器可运行的JS,而需要用到该模块的项目则利用git submodule的方式引入。那么,另外一个重要的问题,当公共模块版本更新之后如何自动地更新相应的项目呢?我们用到了Gitlab的CI/CD功能。

You can set up GitLab CI/CD across multiple projects, so that a pipeline in one project can trigger a pipeline in another project.

我们用到了gitlab自身的multiple pipelines的功能,当公共模块发生变化时,会触发用到它的项目进行CI/CD的流程,示例代码:

staging:
  variables:
    ENVIRONMENT: staging
  stage: deploy
  trigger: my/deployment
复制代码

好像找到了我们想要的方案。

NPM dependency

实际上NPM dependency和上面的Gitlab Submodule如出一辙。不同的是,首先需要把公共模块打包成NPM包放到我们自己的registry里面,然后相应的项目使用@latest来获取公共模块的最新版本,那么trigger的方式也是使用Gitlab的multiple pipelines。

这个方案貌似也比较合适。

综上,本来是有四种,在写的过程中又发现了一种,如果再继续研究可能会有更多的解决方案。最简单最能符合需求的是Git Submodule的方式,而作为一个前端,特别是6年的小前端,我可能还是会使用NPM dependency这种方式,毕竟更符合版本管理的模式。但是可能会逐步去演进,先用Git Submodule实现,然后使用NPM dependency替换。倔强脸 😕

References:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享