1. 写在前面:为什么把"拉项目、切分支"单独写一篇
如果评选程序员最常踩的坑,"环境准备"绝对排前三。你以为的二次开发是从改代码开始的,实际上大多数人的二次开发死在第一步——项目拉不下来、分支选错了、跑起来一堆报错,最后发现是版本不对。
RuoYi-Vue是目前国内使用面很广的一套后台管理脚手架,基于Spring Boot + Vue,代码生成、权限管理、定时任务这些基础能力都封装好了。做二次开发的人通常分两类:一类是公司内部系统需要快速落地,另一类是接私活想省时间。无论哪种,拿到这套代码之后的第一件事绝对不是写功能,而是把项目干净、正确地拉到本地,并锁定一个合适的分支作为开发基线。
这篇是RuoYi-Vue二次开发系列的第一篇,只讲一件事:怎么把项目从Gitee上拉下来,以及为什么切换分支这件事值得单独拿出来说。内容基于我过往多次搭建这套环境的实际操作经验,尽量把每一步的"为什么"也讲清楚。
2. 拉取前的关键决策:你要的是哪个版本的RuoYi-Vue
2.1 先搞清楚RuoYi的几个兄弟项目
很多人搜"RuoYi"会出来一堆仓库:RuoYi、RuoYi-Vue、RuoYi-Cloud、RuoYi-App,还有RuoYi-Vue-Plus这类第三方分支。初次接触特别容易懵。
简单梳理一下:
- RuoYi(单体版):基于Thymeleaf服务端渲染,前后端不分离,适合小型项目。
- RuoYi-Vue:前后端分离,前端Vue + 后端Spring Boot,是目前最主流的选择。
- RuoYi-Cloud:微服务版本,引入了Nacos、Gateway等组件,适合中大型项目。
- RuoYi-App:移动端版本,基于uni-app。
- RuoYi-Vue-Plus:社区维护的增强版,集成了更多工具,但不是官方仓库。
如果你不是明确要做微服务架构,我的建议是直接选RuoYi-Vue。它是在官方仓库中活跃度最高、问题解决方案最多、社区资料最全的一个版本。二次开发最怕的不是功能不够,而是踩了坑搜不到解决方案,选RuoYi-Vue能让你在遇到问题时多出好几倍的搜索命中率。
2.2 官方仓库地址与分支结构
RuoYi-Vue的官方Gitee仓库地址是https://gitee.com/y_project/RuoYi-Vue。注意,如果你在GitHub上搜,也能搜到RuoYi-Vue的镜像仓库,但Gitee这边是主仓库,更新最及时,优先从Gitee拉。
仓库默认分支是master,但实际项目里master不一定是你该用的分支。RuoYi-Vue的官方仓库会维护多个分支,常见的有master(当前开发版)和以版本号命名的分支(如v3.8.7这类),以及一些标识为不再维护的旧分支。
这里有个很关键的认知:分支的命名背后是版本策略。master分支上的代码是持续更新的,今天拉的和下个月拉的可能就不一样。如果你要基于一套稳定的代码做二次开发,并希望后续能跟着官方升级打补丁,那么选择一个固定的版本分支会更稳妥。
我之前接过一个项目,客户要求在这套框架上做三年以上的长期维护。当时我直接选了当时最新的版本号分支作为基线,而不是master,原因很简单:master上随时可能引入新功能或调整接口,一旦跟着更新,自己改过的业务代码就可能冲突。锁死版本分支,等于锁死了一个可预期的边界。
3. 实操环境准备与拉取动作拆解
3.1 你需要提前装好的工具
在真正执行git clone之前,先把环境检查一遍。清单不复杂,但每一件都别漏:
- Git客户端:Windows建议用Git for Windows,装完自带Git Bash。
- TortoiseGit:可选,但Windows下操作小乌龟确实直观,尤其是右键菜单式操作,对新手友好。
- JDK:RuoYi-Vue基于JDK 8开发,虽然新版能兼容更高版本,但建议用JDK 8(如1.8.0_202),避免后续编译遇到莫名问题。
- Maven:版本3.6以上即可,需要配置国内镜像仓库,否则首次拉依赖会非常痛苦。
- Node.js:前端基于Vue 2,建议使用Node 14或16版本,不要直接上最新的Node 20+,Vue 2项目的依赖兼容性会出问题。
- IDE:后端用IntelliJ IDEA,前端用VSCode或IDEA都行,我这里以后端为主的流程来演示。
3.2 Gitee与Git的关联配置
拉取项目之前需要先配置好SSH密钥,否则每次Push/Pull都要输账号密码,而且部分操作会受限于HTTPS方式。虽然标题里写的是"拉取项目",但日常开发中你不可能只拉一次,后续迭代提交、拉取更新都会用到,所以一次性配置好SSH很有必要。
在Git Bash中执行以下步骤:
# 第一步:检查是否已有SSH密钥 ls -al ~/.ssh # 第二步:如果没有,生成新的密钥(邮箱换成你自己的) ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # 第三步:查看公钥内容 cat ~/.ssh/id_rsa.pub复制公钥内容,打开Gitee网站,进入"设置" -> "SSH公钥",粘贴保存。然后验证一下:
ssh -T git@gitee.com看到Hi xxx! You've successfully authenticated就说明配置成功。
如果你用TortoiseGit,还可以在右键菜单里找到"Settings" -> "Network" -> "SSH Client",确认指向的SSH工具路径正确。这个细节容易被忽略,特别是装了多个Git客户端的情况下,TortoiseGit可能找不到正确的SSH客户端,导致连接失败。
3.3 拉取项目的两种方式与选择建议
方式一:直接用Git Bash。
# 推荐用SSH方式,避免了HTTPS的密码问题 git clone git@gitee.com:y_project/RuoYi-Vue.git方式二:用TortoiseGit。
在本地目录右键 -> "SVN Checkout"(这里不是SVN,是TortoiseGit的右键菜单翻译问题,实际是"Git Clone") -> 填写仓库URL和目录 -> 确认。
如果你第一次接触,我用个生活化的类比说明这两种方式的区别:Git Bash是命令行工具,就像用手机手工输号码打电话;TortoiseGit是图形化界面,就像通讯录里点名字直接拨号。前者灵活但需要记忆命令,后者直观但功能入口有时候藏得深。我自己的习惯是命令行为主,TortoiseGit作为辅助查看状态和对比差异,因为命令行在脚本化和批量操作上有不可替代的优势。
拉取完成后,你会看到RuoYi-Vue目录下有ruoyi-admin、ruoyi-framework、ruoyi-system、ruoyi-ui、ruoyi-generator、ruoyi-common等模块,还有个sql目录是数据库脚本,这个后续初始化数据库会用到,先记住它的位置。
4. 分支切换:这不是一个动作,而是一套规范
4.1 为什么拉完代码第一件事是切分支
我见过不少人拉完项目直接就在默认分支上开始改代码。短期的确省事,但问题很快就来了:你改了一半,官方推送了新代码,你git pull之后发现自己改的文件和官方的更新冲突了,解决冲突花掉的时间和精力远超最开始切分支那两分钟。
正确的做法是:拉取完成后立即切换到你要作为开发基线的分支,然后在该分支上拉一条自己的开发分支,或者如果只是个人维护,就基于该分支直接开发。
用一句通俗的话说:你租房子住,不能直接改造房东的房子,得先签好租约,明确自己住在哪套房里,再考虑怎么装修。分支就是这层"租约边界",它保证你的改动和官方维护的版本互不污染。
4.2 查看分支与切换分支的具体操作
先用命令看当前仓库有哪些分支:
# 查看本地分支 git branch # 查看远程分支 git branch -r # 查看全部分支(含远程跟踪信息) git branch -a刚拉下来的项目,本地默认会在master分支上,远程分支信息已经同步。此时你可以查看远端有哪些版本分支:
git branch -a官方仓库通常输出类似这样:
* master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/origin/v3.8.7 remotes/origin/v3.8.8切换分支的命令特别简单:
git checkout -b v3.8.8 origin/v3.8.8这里拆开解释下这个命令的含义:git checkout -b表示创建并切换到一个新分支,v3.8.8是这个新分支的本地名称,origin/v3.8.8是指定这个本地分支跟踪远程的v3.8.8分支。这条命令同时完成"创建本地分支、关联远程分支、切换到该分支"三件事。
如果你想基于master创建自己的开发分支,可以这样:
git checkout -b dev_mine origin/master这样你就有了一个属于自己的本地开发分支,之后所有改动都提交在这个分支上,不会影响master。
4.3 TortoiseGit下切换分支的操作路径
如果你习惯图形界面,在项目文件夹上右键 -> "TortoiseGit" -> "Switch/Checkout"。弹出的对话框里,在"Branch"下拉框选择远程分支(带上origin/前缀的那个),或者直接在"Ref"输入框里填写分支名。下方有个"Create New Branch"的选项,勾选后可以输入新的本地分支名,效果等同于git checkout -b。
这里有个容易踩的坑:窗口下方的"Branches"列表里默认显示的是本地分支,很多人选完本地分支点了确定,结果发现代码没变成远程的新版本。正确的操作是先选中远程分支,再点击"OK"。刚开始用TortoiseGit切分支的朋友在这一点上翻车概率极高,建议操作完立刻执行git branch核实一下当前所在分支。
4.4 切换分支后立刻要做的验证
切换分支成功不等于万事大吉,你还得确认环境是否匹配。做三件事:
第一,确认当前分支。
git branch第二,查看当前分支与远程的同步状态。
git status如果输出Your branch is up to date with 'origin/v3.8.8',说明分支已正确关联。
第三,检查项目版本标识。打开RuoYi-Vue目录下的pom.xml,看<version>标签里的版本号是否与你的分支号一致。这个检查看似多余,但能避免一种常见失误:分支切过去了,但IDE缓存里还是旧版本的依赖,后续启动报错让你怀疑人生。
5. 实操记录:从Gitee拉取到本地跑通的完整过程
5.1 拉取项目实录
我以一次实际操作为例,完整记录从拉取到项目导入的过程。
在本地创建好工作目录,比如D:\workspace,打开Git Bash,执行:
cd /d/workspace git clone git@gitee.com:y_project/RuoYi-Vue.git这里我用的是SSH地址。如果你没配置SSH,也可以用HTTPS地址:
git clone https://gitee.com/y_project/RuoYi-Vue.git两种方式的结果一样,但HTTPS每次推送会要求输入Gitee的账号密码,SSH则不需要,这也是我推荐SSH的原因。
克隆完成后,进入项目目录:
cd RuoYi-Vue git branch -a看到远程分支列表后,执行:
git checkout -b v3.8.8 origin/v3.8.8我用v3.8.8举例,实际操作时你以仓库当前存在的版本分支为准,也可以直接用master。不过我做二次开发的习惯是选择发布版分支,因为维护性和稳定性都更好,这点前面已经解释过。
5.2 数据库初始化与后端启动
RuoYi-Vue需要MySQL数据库,版本建议5.7或8.0。在MySQL中创建数据库:
CREATE DATABASE IF NOT EXISTS ruoyi-vue DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后找到项目里的sql目录,里面有ry_2024xxxx.sql和quartz.sql两个脚本。ry_开头的是主库脚本,quartz.sql是定时任务相关的表。用命令行导入:
mysql -u root -p < ry_2024xxxx.sql mysql -u root -p < quartz.sql或者用Navicat直接导入,注意选择目标数据库后再运行脚本,不然表会建到别的库里。
导入完成之后,修改后端配置。打开ruoyi-admin/src/main/resources/application-druid.yml,把数据库连接信息改成自己的:
url: jdbc:mysql://localhost:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 你的密码然后启动ruoyi-admin模块下的RuoYiApplication主类,看到Spring Boot启动日志里出现Started RuoYiApplication就说明后端起来了。
最后执行mvn clean install -DskipTests或直接通过IDE构建,确保所有模块编译通过。
5.3 前端依赖安装与启动
前端在ruoyi-ui目录下。打开终端,进入该目录:
cd ruoyi-ui npm install这里有个实战提醒:如果npm install非常慢,大概率是因为没有配置淘宝镜像。执行:
npm config set registry https://registry.npmmirror.com然后再跑npm install。安装完成后启动开发服务器:
npm run dev默认端口是80,启动成功后浏览器访问http://localhost,用默认账号admin、密码admin123登录,看到首页就说明前后端联调通了。
6. 分叉点上的决策:master当基线还是版本分支当基线
6.1 两种选择的利弊对比
很多人在"用哪个分支做二次开发基线上"拿不定主意。我做了张简表,方便你权衡:
| 对比维度 | 用master分支 | 用发布版本分支 |
|---|---|---|
| 功能新鲜度 | 最新,包含未发布的改动 | 相对稳定,经过测试 |
| 文档匹配度 | 低,网上教程可能对不上 | 高,大多教程基于版本分支编写 |
| 官方升级路径 | 直接拉取即可 | 需手动合并版本间差异 |
| 长期维护成本 | 高,易发生冲突 | 低,基线明确 |
| 适合场景 | 尝鲜、学习、短期项目 | 正式二次开发、商用交付 |
表格总结一句话:如果你打算把这个项目当真项目来养,选版本分支;如果你只是随便看看功能,选master也行。
6.2 我踩过的一次分支选择坑
我曾经在某个项目里直接用master做基线开发,开发到第三个月,官方推送了一次比较大的依赖版本升级,涉及Spring Boot和某安全组件的版本调整。我执行git pull后,自己改过的几个核心业务类全部冲突,而且因为官方调整了整个依赖体系,导致本地编译都过不了。那一次花了我整整一天去解决冲突和适配新版本。
后来我总结了一个原则:二次开发的主分支,一定要和官方维护分支划清界限。要么选一个发布版本分支做开发基线,要么基于master拉一条独立开发分支并删除本地的master跟踪关系,避免误操作把官方更新拉进自己的代码中。
正确的隔离方式:
# 基于发布分支创建业务开发分支 git checkout -b dev_company origin/v3.8.8 # 推送业务分支到自己的远程仓库(如果你有) git push origin dev_company这样你的dev_company分支和官方的v3.8.8有共同的起点,但之后各走各路,你的业务提交全在dev_company上,官方更新只在v3.8.8上。需要同步官方更新时,再单独执行合并:
git checkout dev_company git merge origin/v3.8.8这个流程兼顾了"代码隔离"和"可升级性"两个诉求。
6.3 本地分支太多导致混乱的解决办法
分支管理还有一个很实际的问题:开发时间长了,本地一堆分支,有时候自己都忘了哪些是干嘛的。我建议建立一套分支命名约定,比如:
dev_业务名_日期:日常开发分支fix_问题编号:bug修复分支feat_功能名:新功能开发分支
如果你的团队规模小,也可以更简单:只有一个develop分支作为集成分支,个人开发时直接在上面提交。关键是团队内部要达成一致,否则分支规范本身会成为新的混乱源。
7. 常见问题与排查技巧实录
7.1 Gitee拉取项目时报"Permission denied (publickey)"
这个报错几乎每个刚配SSH的人都会遇到。原因基本有三种:
第一种,你没有把公钥添加到Gitee后台。回到cat ~/.ssh/id_rsa.pub,完整复制公钥内容,粘贴到Gitee的SSH公钥设置页面。
第二种,你添加公钥的时候带了空格或换行符。这个坑很容易被忽略,特别是从终端复制长串文本时,末尾可能带上一个换行。粘贴完保存后重新测试ssh -T git@gitee.com。
第三种,多SSH密钥环境下Git选错了密钥。如果你本机有多个SSH密钥(比如公司GitLab一个、个人Gitee一个),需要在~/.ssh/config中配置指定:
Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_rsa_gitee7.2 切换分支后代码内容没变化
这种情况通常不是你操作错了,而是你切换的目标分支和当前分支在目标目录下的内容相同。比如v3.8.8和master在某个文件上没有差异,你切过去当然看不到变化。
但如果确认两个分支应该不同,却没有任何变化,那很可能是工作区有未提交的修改,Git阻止了切换。此时用git status查看工作区状态,把改动提交或暂存后再切分支。
7.3 npm install 报 ERESOLVE unable to resolve dependency tree
这个问题在Vue 2项目里太常见了,尤其是Node版本太高时。RuoYi-Vue基于Vue 2和旧版依赖,在高版本Node里容易出现依赖解析失败。
解决办法有两种:
第一种,降低Node版本到14或16。可以用nvm管理Node版本,在项目目录下执行:
nvm use 16第二种,使用legacy-peer-deps强制兼容旧依赖解析模式:
npm install --legacy-peer-deps这个参数等于告诉npm:依赖冲突先不管,按传统方式装。RuoYi-Vue这种经过大量实践的项目,依赖关系实际上是兼容的,只是新版npm的解析规则太严格。
7.4 后端启动时报数据库连接失败
先确认MySQL服务是否启动,Windows下可以在服务管理里查看MySQL服务状态。再检查application-druid.yml里的用户名密码是否匹配,特别注意密码中的特殊字符是否被YAML解析成其他含义。如果密码包含@或冒号这类字符,建议用单引号包起来。
还有一个小概率问题:数据库字符集。RuoYi-Vue的初始化脚本包含中文数据,如果库字符集不是utf8mb4,启动后查询数据可能乱码。建库时一定带上DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci。
7.5 前端能打开但接口全部401
后端权限过滤器在起作用,说明前端没带上登录token。先确认前端访问的接口地址和后端实际地址是否一致,看ruoyi-ui/.env.development里的VUE_APP_BASE_API配置:
ENV = 'development' VUE_APP_BASE_API = '/prod-api'这里的/prod-api是前端代理前缀,真正转发的地址在vue.config.js里的proxy配置。如果后端接口地址和代理目标不一致,登录接口就会请求到错误地址,自然拿不到token。
8. 分支切换之外:定义一个自己的"上游"管理策略
分支切换这个主题讲到最后,我想补充一个很多人忽略但长期收益极高的习惯:定义清楚你的"上游"是什么。
在Git世界里,"上游"指的是你的本地分支跟踪的远程分支。默认拉取RuoYi-Vue官方仓库后,本地分支的上游是origin/master或origin/v3.8.8,这里的origin指向官方仓库。但在真实二次开发中,你不应该直接往这个origin推送代码。
正确姿势:在Gitee上创建自己的仓库(比如company/RuoYi-Vue),把它添加为另一个remote,命名为myorigin:
git remote add myorigin git@gitee.com:company/RuoYi-Vue.git git push -u myorigin dev_company这样你的工作区同时拥有两个remote:origin代表官方仓库,myorigin代表自己的代码仓库。日常开发中,从origin拉取官方更新,向myorigin推送自己的代码。这个拓扑结构干净清晰,也便于多人协作时彼此之间用myorigin作为交互中枢。
别嫌麻烦,这个动作值得做。原因很简单:它把"官方代码"和"我的代码"变成了两个物理隔离的仓库,无论后续官方仓库怎么变化,自己的代码仓库始终是稳定的交付基线。
9. 关于这套环境的几个实践体会
我在不同阶段用RuoYi-Vue做过几个大小不一的项目,感触比较深的有几点:
第一,分支切换的复杂度往往不在执行,而在决策。什么时候切、切到哪里、切完怎么办,这些问题想清楚,命令本身两秒钟就能执行完。
第二,刚拉完项目别急着写代码,先把"数据库初始化 -> 后端启动 -> 前端启动 -> 页面可登录"这条链路完整跑通一遍。这一步确认了,相当于给你的开发环境交了个底,后面所有功能开发都有了一个可验证的起点。
第三,RuoYi-Vue这类成熟脚手架,最大的价值不是代码本身,而是它帮你规范了项目结构、权限模型和通用能力。二次开发的时候,尽量顺着它的既定模式走,不要一上来就推翻它的架构设计。很多功能官方已经预留了扩展点,在扩展点上做加法,比在核心逻辑上做替换,省力且安全得多。
下一篇我会讲真正进入二次开发后的第一个核心动作——代码生成器的使用和前后端联调细节。代码生成器是RuoYi-Vue拉开和其他脚手架差距的地方,也是最容易出体验问题的地方,到时候边操作边聊。