一套属于前端的版本控制系统!更新!!不求人!!!

转自: 忙碌的豆己

前言

公司之前更新前端代码需要远程到服务器后,将对应打包好的项目代码复制到目录中去。在更新频繁的时候,中间所浪费的无用时间就变的很多,加上回退版本还要涉及到备份的操作,多服务器的时候还要记住密码账号等等等操作就会觉得繁琐。再加之人员众多,服务器的安全性也无法得到保障。遂计划开发出一套前端版本控制的解决方案。

经过2020一整年,3个大版本的迭代,最终完成了正式的1.0版本。包括版本上传,切换,测试,上线,删除,备份等功能,很好的解决的公司内部问题。在这里分享出我自己的三个版本的思路(仅有思路以及部分代码),有不同想法和各种建议欢迎讨论~

版本1-基于git和nodejs

最开始的想法很简单,既然git在版本控制的方面做得很好,那么以它为核心去构建一套系统就成为了第一种解决方案。

一、思路

  1. 创建一个用于放置打包好文件的git项目

  2. 在本地和服务器端都拉取该git

  3. 本地项目更新打包后,提交git,在服务端的git接收到更新的指令后,进行拉取,完成更新。

二、知识点

  1. git hook(git操作会触发的钩子函数)

  2. 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;
})

五、缺点

  1. 需要新建git项目,改git配置,还要再双端拉取,前期准备过多。

  2. 没有版本控制功能,要回退只能代码回退后重新打包上传。

  3. 一但服务器端的项目文件夹发生改动,那么在拉取的时候就会被识别冲突(发生率高)

六、优点

  1. 拥有git的版本管理

  2. 只需要正常的git提交就完成自动的更新

版本2-基于nodejs

虽然说基于git,可以不用做一些版本的事情,但同样局限性很大,并且所需的版本控制也没有到那么细致的地步,所以版本2放弃了git,完全使用nodejs读文件,写文件,解压文件的能力进行开发,并且在此基础上,实现可视化的管理。

一、思路

  1. 在服务端新建一个网页用于可视化

  2. 在服务端创建一个专门用于版本管理的文件夹

  3. 在服务端创建node服务,读取该文件夹中的各种版本信息并展示

  4. 本地访问服务器的网页的时候上传压缩后的文件并且表明版本信息,服务器接收后,储存在版本管理的文件夹中

  5. 在网页上点击上线后,解压对应的压缩包至项目目录,并且修改版本信息

最终效果如下:

二、知识点

  1. 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('自动更新启动~');
})

五、缺点

  1. 使用文件,和文件夹来管理版本过程比较复杂(验证存在,打开文件读取,修改值,储存)

  2. 扩展性十分差

  3. 涉及到文件名的无法重名

  4. 多站点无法兼容,必须一个站点部署一整套服务

六、优点

  1. 脱离git所带来的的束缚以及问题

  2. 有可视化的界面

  3. 版本切换操作方便简单

  4. 开发者本地无需进行配置,只负责上传

版本3-基于nodejs以及数据库

有了可视化界面让上版本变得十分方便,但一方面由于单纯使用文件,来进行管理,扩展性十分差,比如鉴权,多站点,多平台,测试站正式站分离等,所以引入数据库来储存版本信息。

一、思路

版本除了将版本数据搬进数据库外,主要解决多站点的问题,即使用一个平台可以更新各服务器的前端。主要来讲讲这里的思路

1.主服务

主服务用于调用数据库来进行版本管理

2.分服务

其他服务器上只要部署分服务,该服务接收到来自主服务的请求后,进行更新操作,最后返回是否成功

功能部分截图:

二、知识点

  1. nodejs

  2. 数据库

三、坑

暂无

四、具体实现

1.数据库

数据库的设计因人而异,只要做到能够版本控制就好。(仅供参考)

  1. 部门表:id,部门名称

  2. 平台表:id,平台名称,所属部门id

  3. 项目表:id,所属平台id,项目名称,正式站项目地址,正式站请求地址,测试站项目地址,测试站请求地址,变动时间

  4. 版本表:id,版本名称,所属项目id,oss地址,上线状态,测试状态

2.主服务

  1. 部门的获取

  2. 平台的获取

  3. 项目的增删改查

  4. 版本的增删,上线以及测试

3.分服务

分服务只有上线功能,其原理与版本2中的上线一致,忘记的倒回去看看~

五、缺点

  1. 目前还是使用压缩包的形式,即打包项目后在压缩成zip包,再上传,若有更好的想法,欢迎交流

  2. 系统中还缺乏鉴权功能

  3. 上传版本还是比较复杂

六、优点

就除了以上缺点就全是优点!

后记

该系统已经在线上运行了一段时间了,也改变了我们前端的更新方式,也算是今年做的比较出色的东西吧。当然系统中差的东西还有很多,相信随着使用的人慢慢变多,以及吸收各个方面的意见,它会完善成一个很好用的工具~


推荐阅读:
后端,你再不懂vue就out了

Vue 3.0  算法及原理

我在vue3.0团队内部的分享

一个基于SpringBoot + Mybatis + Vue的代码生成器

Vue的异步更新实现原理

Vue编程的团队代码规范


猜你喜欢

转载自blog.csdn.net/weixin_45727359/article/details/113533373
今日推荐