一套属于前端的版本控制系统!更新!!不求人!!!
(给前端大学加星标,提升前端技能.)
转自: 忙碌的豆己
前言
公司之前更新前端代码需要远程到服务器后,将对应打包好的项目代码复制到目录中去。在更新频繁的时候,中间所浪费的无用时间就变的很多,加上回退版本还要涉及到备份的操作,多服务器的时候还要记住密码账号等等等操作就会觉得繁琐。再加之人员众多,服务器的安全性也无法得到保障。遂计划开发出一套前端版本控制的解决方案。
经过2020一整年,3个大版本的迭代,最终完成了正式的1.0版本。包括版本上传,切换,测试,上线,删除,备份等功能,很好的解决的公司内部问题。在这里分享出我自己的三个版本的思路(仅有思路以及部分代码),有不同想法和各种建议欢迎讨论~
版本1-基于git和nodejs
最开始的想法很简单,既然git在版本控制的方面做得很好,那么以它为核心去构建一套系统就成为了第一种解决方案。
一、思路
创建一个用于放置打包好文件的git项目 在本地和服务器端都拉取该git 本地项目更新打包后,提交git,在服务端的git接收到更新的指令后,进行拉取,完成更新。
二、知识点
git hook(git操作会触发的钩子函数) nodejs
三、坑
正常情况下,git的钩子post-receive在接收到更新的时候会触发,利用这个钩子在进行git pull就可以完成更新,但在windows下无法正确触发(这点不知道为何,希望了解的大佬能科普下,球球了)
四、具体实现
由于坑的原因,不得不换一种思路,好在git钩子中的pre-push(git提交)能够正确触发,那么在服务器搭建一个node服务用于接收请求后到对应的目录git pull。
1. 本地git hook(pre-push)
采用curl命令直接模拟请求,但windows的cmd上不支持,所以要安装curl命令(具体方法:https://www.cnblogs.com/zhuzhenwei918/p/6781314.html)接着进入 .git/hooks 文件夹将里面随便哪个文件命名成 pre-push 并输入
#!/bin/sh
exec curl 192.168.0.83:1911/update?url=d:/wwwroot/dkdWeb/pages/copy
在推送前触发钩子函数访问服务器上的某个端口,url参数用于找到项目位置,并更新
2. 服务器node服务
搭建最简单的node服务这里用的是express框架,这个服务主要是用于在接收到请求的时候,根据参数不同,在不同的项目中执行git pull更新的动作
var express = require('express');
var app = express();
var cmd = require("node-cmd");
//设置跨域访问
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
//写个接口
app.get('/update', function (req, res) {
res.status(200);
res.json('执行成功');
if(req.query.url){
setTimeout(function(){
cmd.run("cd /d "+req.query.url+" & git pull");
},5000)
}
});
//配置服务端口
var server = app.listen(1911, function () {
var host = server.address().address;
var port = server.address().port;
})
五、缺点
需要新建git项目,改git配置,还要再双端拉取,前期准备过多。 没有版本控制功能,要回退只能代码回退后重新打包上传。 一但服务器端的项目文件夹发生改动,那么在拉取的时候就会被识别冲突(发生率高)
六、优点
拥有git的版本管理 只需要正常的git提交就完成自动的更新
版本2-基于nodejs
虽然说基于git,可以不用做一些版本的事情,但同样局限性很大,并且所需的版本控制也没有到那么细致的地步,所以版本2放弃了git,完全使用nodejs读文件,写文件,解压文件的能力进行开发,并且在此基础上,实现可视化的管理。
一、思路
在服务端新建一个网页用于可视化 在服务端创建一个专门用于版本管理的文件夹 在服务端创建node服务,读取该文件夹中的各种版本信息并展示 本地访问服务器的网页的时候上传压缩后的文件并且表明版本信息,服务器接收后,储存在版本管理的文件夹中 在网页上点击上线后,解压对应的压缩包至项目目录,并且修改版本信息
最终效果如下:
二、知识点
nodejs
三、坑
由于上传的是整个压缩包,这会导致服务器上的压缩包越来越多,储存占用的越来越大,所以需要前端先上传到oss,再把得到的oss地址上传上去
四、具体实现
1.项目列表
每个项目即为一个文件夹,通过读取版本管理文件夹下的文件夹以获取项目列表
2.项目信息
每个项目文件夹中拥有两个文件。一个用于存放项目解压地址,第二个用于存放版本信息
3.项目操作
所有对于项目的操作,包括上线,编辑,删除,新增项目,新增版本等,都是对文件或文件夹的修改与新增。
4.上线
上线其实就是找到对应版本指到的oss地址,进行下载后,解压到对应目录中,并且把版本信息变动的操作。
const express = require('express'),
app = express(),
bodyParser = require('body-parser'),
checkToken = require('./checkToken'),
fs = require('fs'),
compressing = require("compressing"),
tools = require('./tools/tools.js');;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//设置跨域访问
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
app.use(checkToken);
app.post('/toLine',async (req, res) => {
let fdata = req.body.pAddr;
let download = await tools.downloadFileAsync(req.body.ossAddr.replace('https', 'http'), __dirname + '\\download.zip');
fs.exists(fdata, function (exists) {
if (exists) {
tools.delDir(fdata, false)
compressing.zip.uncompress(__dirname + '\\download.zip', fdata, { zipFileNameEncoding: 'gbk' })
.then(() => {
fs.unlink(__dirname + '\\download.zip', () => { });
tools.handleRes(res, true, '上线成功');
})
.catch(err => {
console.log(err)
tools.handleRes(res, false, '解压失败')
});
}
else {
tools.handleRes(res, false, '项目地址不存在')
}
})
});
app.listen(8899, function () {
console.log('自动更新启动~');
})
五、缺点
使用文件,和文件夹来管理版本过程比较复杂(验证存在,打开文件读取,修改值,储存) 扩展性十分差 涉及到文件名的无法重名 多站点无法兼容,必须一个站点部署一整套服务
六、优点
脱离git所带来的的束缚以及问题 有可视化的界面 版本切换操作方便简单 开发者本地无需进行配置,只负责上传
版本3-基于nodejs以及数据库
有了可视化界面让上版本变得十分方便,但一方面由于单纯使用文件,来进行管理,扩展性十分差,比如鉴权,多站点,多平台,测试站正式站分离等,所以引入数据库来储存版本信息。
一、思路
版本除了将版本数据搬进数据库外,主要解决多站点的问题,即使用一个平台可以更新各服务器的前端。主要来讲讲这里的思路
1.主服务
主服务用于调用数据库来进行版本管理
2.分服务
其他服务器上只要部署分服务,该服务接收到来自主服务的请求后,进行更新操作,最后返回是否成功
功能部分截图:
二、知识点
nodejs 数据库
三、坑
暂无
四、具体实现
1.数据库
数据库的设计因人而异,只要做到能够版本控制就好。(仅供参考)
部门表:id,部门名称 平台表:id,平台名称,所属部门id 项目表:id,所属平台id,项目名称,正式站项目地址,正式站请求地址,测试站项目地址,测试站请求地址,变动时间 版本表:id,版本名称,所属项目id,oss地址,上线状态,测试状态
2.主服务
部门的获取 平台的获取 项目的增删改查 版本的增删,上线以及测试
3.分服务
分服务只有上线功能,其原理与版本2中的上线一致,忘记的倒回去看看~
五、缺点
目前还是使用压缩包的形式,即打包项目后在压缩成zip包,再上传,若有更好的想法,欢迎交流 系统中还缺乏鉴权功能 上传版本还是比较复杂
六、优点
就除了以上缺点就全是优点!
后记
该系统已经在线上运行了一段时间了,也改变了我们前端的更新方式,也算是今年做的比较出色的东西吧。当然系统中差的东西还有很多,相信随着使用的人慢慢变多,以及吸收各个方面的意见,它会完善成一个很好用的工具~