1.结构化管理
git-submodule是一种原生支持的仓库管理方案,他允许像pnpm一样使用链接方式链接你的远程仓库,不用将仓库强行绑定到一起,十分方便。
同一般的统一仓库管理方案不同,这种分离管理方案将仓库进行了解耦,无需将前后端放到同一个仓库内进行管理。
结构化管理使用方式也很简单,我们首先需要创建前端仓库、后端仓库,将两个仓库上传到云端,例如Github。
之后在本地创建一个空仓库project-main,执行以下命令将前后端仓库嵌入主仓库中:
git submodule add <前端仓库URL> web
git submodule add <后端仓库URL> server
创建完成后,git会自动将云端仓库数据拉取到本地,此时将仓库上传到云端Github,即可完成主仓库结构化管理。
这种仓库管理方式同旧的仓库有所不同,具体管理示例可以参考这个图表。
结构化管理可以很方便的将前端和后端仓库进行统一管理,同时保证了前端和后端的仓库分别存储,但是有了一个主项目仓库,依旧可以从一个项目中管理前端和后端两个项目。
使用了一个大的父工程文件作为基础,内部包含了项目前端和后端两个子模块。
结构化管理的两个子模块都是链接引用的方式进行引用,并没有真实存在项目中。只保留了子模块仓库最新的提交ID。
2.优缺点
全结构化管理方式无论是前端还是后端,两个代码仓库都互相独立互不影响,父工程文件只是将两者进行链接,不会对子工程构成侵入。
区别于完全结构化管理,还有一种半结构化管理方式。
将项目的后端作为父工程,然后在后端中导入前端的子工程,这种方式好处是借助链接管理的方式独立前端,让后端仓库不污染。
结构化管理和半结构化管理,解决了最原始的将项目前后端都放到一个仓库中,无论谁改都得同步痛点,前后端耦合严重,重复提交拉取过于繁琐,同时不利于仓库代码结构整洁。
但凡事必有代价,使用结构化管理,也需要注意一些额外的问题。
包括但不限于强绑定git仓库,普通clone拉取仓库为空,指针错位,忽略文件作用于出错,后端模块依赖出错,前端不加载。
3.问题解决方案
3.1.clone拉取仓库为空
父仓库只会存储子仓库的提交链接指针地址,本身不存储任何子仓库内容,子仓库内容只有在本地开发的时候才会被拉取到你的本地开发环境,云端不存储任何数据,只存储子仓库最新一次提交的指针。
使用结构化管理方式,子仓库更新后必须同步更新父仓库的内容,不然会出现冲突问题,必须在更新子仓库后同步更新父仓库才能解决。
同时,使用结构化分离式仓库管理,在主仓库简单的 git clone 不会下载子模块代码。
必须使用
git clone --recursive 完全拉取,或者后续执行git submodule update --init --recursive
# 方式一:克隆时直接带上参数(推荐,一步到位)
git clone --recursive <主项目仓库地址>
# 方式二:如果已经克隆了主项目,再拉取子模块
git submodule init
git submodule update
使用控制台直接clone,实际文件夹内部全都是空的,相当于你只拉下来一个主仓库,子模块的文件夹默认是空的。
凡事皆有对策,如果你使用的是idea,那么就不用担心了,idea会自动帮你处理这些问题,你只需要将项目使用自带的克隆到idea中运行就可以,idea会自动帮你处理依赖关系。
3.2.指针错位
结构化管理仓库会出现指针错位问题,无论你是直接拉取仓库还是使用idea拉取仓库,头指针会指向最后提交的游离分支。
从远程仓库新拉取下来的项目,一定要注意项目配置。

例如,后端项目中嵌入了远程的前端,现在出现了游离HEAD的情况,那么你需要手动的将本地前端的分支修改为远程的master分支,这样才能保证之后的提交不出错。
如果你没有对设备做配置,那么一定要记得,拉取远程仓库后手动将独立仓库切换到master分支


在有感叹号标记的游离分支,点击签出即可解决分支游离的问题。
也可以使用直接签出功能,效果类似。
3.3.忽略文件作用域
在idea中完成相应的配置后,可能会在你的子模块中生成一些配置文件,这些配置文件需要做一下处理。就像下面需要介绍的.iml文件。
.iml 文件是特定于模块的配置文件。在 Git 的逻辑中,子模块是一个独立的仓库。父工程只记录子模块的 Commit ID(指针) ,而不直接管理子模块内部的文件列表。
这些配置文件理论上不应该上传到远程仓库,所以一定要在你的子工程里面配置提交忽略忽略掉这些文件。
子模块的忽略文件只作用于子模块,父模块的忽略文件作用于父模块,但由于继承关系所以子模块也会被忽略,但离开了父模块子模块因为没有忽略配置,所以单独运行的时候不会被忽略。
所以,切记不要在父工程中单独忽略某文件,否则由于忽略继承的原因会导致子模块忽略无法生效。
3.4.后端模块依赖关系
更换完成分支后,还需要手动添加一下模块依赖关系。
首次使用idea打开拉取的项目后,下方会弹出消息提示找到模块,直接导入即可自动化完成加载。
如果错过了,那就只能采用下方的配置方式手动配置。
我的后端文件是maven构建的项目对于后端,因此我们需要将pom.xml文件设置为maven项目。同时添加前后端模块到主项目中。
导入模块的方式如下,此处用前端模块举例。



如果你的后端代码爆红,提示找不到相应的的软件包,那说明你的项目模块出现了问题,系统给你选择成了整体的模块而不是后端模块,导致idea找不到目录,无法处理代码。
可以打开任意一个java文件,将鼠标移动到右侧顶端,尝试到右上角的模块选择位置选择你的后端模块,查看代码是否恢复正常。
注:新版idea已完全自动化处理,此方式留档备用。
或者将外部的模块设定为普通的项目默认,什么都不要注册就可以解决问题。
如果主模块被注册成源码,那么你需要将主模块撤销相应的属性,其他的什么都不要,让他成为普通的项目文件。例如下方这样,主仓库模块中什么也没有,既不是源码也不是编译文件,仅仅是空模块。
当然,最简单的解决方式是直接删除你的总项目模块,前后端都是独立存在的,外面的模块只不过是作为一个仓库统一管理便于开发罢了。
例如这样,删除了主模块,只保留后端和前端模块,完美解决找不到文件的问题,项目前后端均可运行。
但这样做对于本地开发来说并不是好事,后期维护还需要手动添加,不然仓库无法提交新代码。
当注册完子模块和相关的项目配置之后,在左上角的git管理页面可以查看当前项目配置的分支属性,在git提交页面中可以查看相应的分支日志和分支标识。
3.5.前端加载
如果项目此时没有加载前端,解决方式在这里。
找到你项目前端的包管理配置文件,右键查看是否有install的安装命令,只要出现了安装命令,说明idea已经识别了前端相关信息,后续只需要安装就好。

等待安装完成,使用显示npm脚本运行一次前端,前端启动项目就会出现在右上角的启动配置中可以一键启动。
至此,所有的项目配置完成,我们还需要一个符合程序能够一键启动项目前后端。
4.复合程序启动
idea提供了复合程序启动的方式,能够一键启动独立的前后端项目,支持同时常规启动,同时以调试模式启动。
打开右上角的启动选项配置,添加一个新复合程序,将前端和后端增加到复合程序中。
启动复合程序,即可一键启动前后端。


Comments NOTHING