为了偷懒,我用google/zx一键自动打包编译了前后端项目并发布到指定环境

简介: 由于正在负责的一个项目,就说前端涉及到PC端、公众号端、APP端的H5、小程序端、可视化大屏端,而PC和APP又通过qiankun引入了微前端的理念。整体一圈下来可能光前端编译打包就要build差不多二十次。而有时候经常性的bug改动,这个时候便只需要进行测试后需要进行小范围的测试。

image.png


大家好,我是 那个曾经的少年回来了。10年前我也曾经年轻过,如今已步入被淘汰的年龄,但现在幡然醒悟,所以活在当下,每天努力一点点,来看看2024年的时候自己会是什么样子吧,2024年的前端又会是什么样子,而2024年的中国乃至全球又会变成什么样子,如果你也有想法,那还不赶紧行动起来。期待是美好的,但是更重要的是要为美好而为之奋斗付诸于行动。


1、前言


由于正在负责的一个项目,就说前端涉及到PC端、公众号端、APP端的H5、小程序端、可视化大屏端,而PC和APP又通过qiankun引入了微前端的理念。整体一圈下来可能光前端编译打包就要build差不多二十次。而有时候经常性的bug改动,这个时候便只需要进行测试后需要进行小范围的测试。


还有一个不得不说,用JavaScript就能写出自动化编译打包的脚本,对于一个前端程序猿来说还是非常的nice。上手也是非常的快。欢迎你也来一起体验加入。

先说一下目前我代码里已经实现的功能 我已将所有代码上传到github了,github地址:github.com/aehyok/zx-d… ,有兴趣的话可以一起研究学习一下


2、实现的功能


2.1、 拉取代码


实现cd到应用后,先git pull拉取代码(没有实现安装依赖的功能,需要手动实现检查)


export const gitPullBy = async(projectName: string, path: string) => {
  try {
     writerLog(projectName, `git pull start`, global.version);
    const gitPullInfo = await $`cd ${path}; git pull;`;
    console.log(gitPullInfo, "pullInfo");
    if (gitPullInfo.exitCode === 0) {
       writerLog(projectName, `git pull end success`, global.version);
    } else {
      console.log("fail", $`$?`);
    }
  } catch {
     writerLog(projectName, `git pull error`, global.version);
  }
};


这里目前可以进行优化处理:比如配置好git仓库地址和对应所在目录后,再自动安装依赖,build编译打包项目


2.2、设置版本号


这里简单啰嗦一下,比如在我们前端项目中一般都有一个显示版本号的地方,可能在设置中,或者我的最下面的某个地方。这是我目前开发的一个项目,如下图所示是微信小程序中显示版本号的地方


image.png


首先我通过 standard-version 这个依赖来更新版本号,自动根据当前版本号进行匹配生成。 我的版本号是通过读取package.json中的version的,所以我可以上面 2.1、 拉取代码后,通过代码先将package.json中的 version版本号进行修改


// 显示版本号的地方
// 引入package.json文件
import config from '../../package.json'
this.version = config.version
export const updateVersion = (path: string) => {
  cd(`${ path }`);
  const packageString = fs.readFileSync(`${path}\\package.json`).toString();
  let packageJson = JSON.parse(packageString)
  packageJson.version = global.version;
  fs.writeFileSync(`${path}\\package.json`, JSON.stringify(packageJson, null, 2))
}


主要通过 nodejsfs模块的 readFileSync ,读取package.json文件,转换为JSON对象,进行修改,然后再通过 fs 模块的 writeFileSync将版本号写回。


当然版本号的获取还有别的很多方式,这里只是我自己想出来比较简单的一种方式,如果你有更简单的方式,咱们可以留言学习一波。


2.3、编译打包项目


修改完前端项目的版本号以后,就是要对项目进行build编译打包了


export const yarnBuildBy = async (path: string) => {
    try {
         oneLogger(`yarn build start ${path}`);
        const buildInfo = await $` cd ${path};yarn build;`;
        console.log(buildInfo, "buildInfo");
        if (buildInfo.exitCode === 0) {
           oneLogger(`yarn build end success`);
        } else {
           oneLogger(`yarn build error: ${buildInfo.stderr}`);
        }
      } catch(error) {
          console.log('yarn build error', error)
           oneLogger("yarn build error");
      }
}


这里我目前使用的 yarn build进行编译前端项目,根据具体的项目可以进行适当的修改,或者进行配置即可。


2.4、对代码仓库进行git tag打标签


因为有时候编译打包后,可能会发现线上的版本代码是有bug的,那么就需要对线上版本的代码进行bug的修复,如果我们自动打好标签,跟线上版本比对后,直接根据当前线上版本的tag生成对应分支的代码即可。


const addTag = async (path: string, isExist: boolean) => {
  const result = await $` cd ${path};
                           git tag -a ${global.version} -m 'chore:version ${global.version}版本号'; 
                           git push origin ${global.version};`;
  if (result && result.exitCode === 0) {
    if (isExist) {
      await oneLogger(`re create tag [${global.version}] success`);
    } else {
      await oneLogger(`create tag [${global.version}] success`);
    }
  }
};


这里我只是简单的进行tag的标记,并推送,其实我们在打tag的时候,首先要尽量检查一下tag是否已经存在,如果存在,考虑一下是否删除重新生成,或者使用新的tag名称等等。


其实这里有一个注意事项: tag标签和分支名称进行不要重复,首先说明一下重复是没问题的,毕竟一个是tag标签,一个是分支,但是有时候我们推送代码的时候没有明确的指定 就会出现问题。当然如果你的git 操作的非常流弊,各种姿势都非常熟练,那肯定是没问题的。比如像我可能就会注意一下尽量保证分支名和tag标签名是不一致的,避免后期产生一些头疼的问题。


2.5、推送源代码到git仓库


上面我们的git tag其实就已经推送到了代码仓库,道理是一样的,加入上面修改版本号以后,我们想将代码文件推送到仓库


const message=`chore: ${buildProject}::commit-version-${global.version}`
const result = await $`cd ${releasePath}; git add . ; sleep 3; git commit -m ${message}; git push origin;`
if(result && result.exitCode === 0 ) {
    await writerLog(name, `git push end success`, global.version);
} else {
    await writerLog(name, `git push error: ${result.stderr}`, global.version); 
}


这里我一键三连, git add .git commitgit push 中间使用sleep 3,沉睡了三秒钟,这样执行 git commit 的时候一般不会出现问题。


2.6、拷贝编译后的打包文件


代码打包编完成之后,是在本地服务器指定位置,假如我们想拷贝到远程服务器


export const copyFile = async() => {
    try {
        const path = global.project.projectName
        const ipAddress = 139.9.184.171
        // const ipAddress = '139.9.184.171'
        const result = await $`scp -r /e/work/git-${global.environment}/release/cms/${path}/* root@${ipAddress}:/usr/local/sunlight/dvs/dvs-ui/${path}/`
        if(result.exitCode === 0) {
            oneLogger(`copy file  [${global.version}] end success`)
        }
        else {
            console.log("fail", $`$?`);
        }
    } catch {
        oneLogger(`copy file [${global.version}] end error`)
    }
}


这里我是将本地代码拷贝到了远程的linux服务器,可以将本地的ssh秘钥拷贝到远程服务器的指定目录。


2.7、将编译的项目文件,单独存放到一个代码仓库


比如这个仓库叫 release仓库


因为有时候一个项目可能涉及到多个端的代码,比如PC有项目,APP的H5也有项目,而小程序里也有H5的项目要打包,项目大了以后,整个编译打包也变的复杂多变,这样就有一个单独仓库当前项目打包编译后的仓库,方便记录,以及回滚,单独某个小项目发布的需求。


这里的代码就比较简单了,上面的代码中也有提到,其实就是将一键三连将代码提交并推送到远程git仓库


export const gitPullBy = async(projectName: string, path: string) => {
  try {
     writerLog(projectName, `git pull start`, global.version);
    const gitPullInfo = await $`cd ${path}; git pull;`;
    console.log(gitPullInfo, "pullInfo");
    if (gitPullInfo.exitCode === 0) {
       writerLog(projectName, `git pull end success`, global.version);
    } else {
      console.log("fail", $`$?`);
    }
  } catch {
     writerLog(projectName, `git pull error`, global.version);
  }
};


其实我这里想了一下,如果对打包编译后的仓库,也打包tag标签,保证线上版本和这个release仓库的,再做一个历史记录进行保存,这样其实很容易方便回滚,比如当前发布的版本是3.5.1,可是突然发现了重大问题,必须回滚,这个时候就需要将线上的版本马上回滚到3.5.0,OK,那么现在马上拉取release仓库中的 tag标签为3.5.0的仓库代码即可。感觉上好像没什么问题。


同时服务器也可以进行历史版本的备份动作,方便回滚操作。


2.8、后端编译也是完全没有问题的


主要就是对构建流程的梳理而已,跟前后端其实是没关系的。


import { $ } from 'zx'
import { gitPull } from './utils/git-pull.mjs';
const path = "/H/work/dvs/server-csharp/"
const collectPath= path + "Services/DVS.Collect.API"
// await gitPull();
const buildInfo = await $`cd ${collectPath}; dotnet publish -o ../../publish/dvs-collect -f net6.0 -r linux-arm64 --no-self-contained;`;
if(buildInfo.exitCode === 0) {
  console.log("build info ok")
} else {
  console.log(`build info error: ${buildInfo.stderr}`)
}
const buildpath = 'dvs-collect'
const ipAddress = '139.9.184.171'   //  139.9.184.171   // 121.37.222.1
const result = await $`scp -r /h/work/dvs/server-csharp/publish/${buildpath}/* root@${ipAddress}:/usr/local/sunlight/dvs/${buildpath}/`
if(result.exitCode === 0) {
    console.log(`copy file end success`)
}
else {
  console.log("fail", $`$?`);
}
// 可以执行本地的server.sh脚本指令 (-t保持登录状态    ssh -t root@139.9.184.171 < server.sh)
// 还可以添加脚本参数
const login = await $`ssh root@${ipAddress} < server.sh`
if(login.exitCode === 0) {
  console.log(`ssh login success`)
}
else {
  console.log("fail", $`$?`);
}


运行完本地的打包编译后,登录远程,并执行server.sh,比如来执行服务的重启等。


3、goploy


来看看这个产品,它在github上是有开源的,开箱即用,简单部署一下就可以使用,感觉还是非常方便的,这是我在自己的window本机部署了一套环境,其实跟我自己写的有很多功能是重复的,当然我做的还算是比较陋跟大佬简直不可比拟,使用上更加的人性化,毕竟通过操作界面就可以完成


image.png


github开源地址github.com/zhenorzz/go…


前端采用的Vue3+TypeScript+ Element-plus 这个前端技术跟我还是非常的匹配,后端采用的是大热的go语言,这个对我来说可能难度稍微大了一些,毕竟没接触过。不过我觉得可能经过一个周左右的时间,应该看懂一点代码,应该问题不大吧,猜测的 当然可能是自己太自信了  哈哈, 明年有时间的话会将这个工具结合自身的使用进行升级一波。可能更贴合于现在公司的使用场景吧。


当然了目前公司也使用了这个工具,已经极大的简化了部署的繁杂,应该说是节省了很多的时间,而且按照这个步骤来,很多时候是不容易出错的。


4、总结


目的就是为了让那些重复性的工作,慢慢的通过工具来替代,将节省下来的时间去研究更有意义的事情,或者去摸摸鱼划划水,是不是更香呢?当然记得不要告诉老板哟? 哈哈  开个玩笑


我的个人博客:vue.tuokecat.com/blog


我的个人github:github.com/aehyok


我的前端项目:pnpm + monorepo + qiankun + vue3 + vite3 + 工具库、组件库 + 工程化 + 自动化


不断完善中,整体框架都有了


在线预览:vue.tuokecat.com


github源码:github.com/aehyok/vue-…

目录
相关文章
|
7月前
|
编解码 人工智能 数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
165 0
|
7月前
|
人工智能 自然语言处理 负载均衡
这款 AI 网关项目简直太棒了,轻松接入OpenAI、LLama2、Google Gem)ini等 100 多种大语言模型!
这款 AI 网关项目简直太棒了,轻松接入OpenAI、LLama2、Google Gem)ini等 100 多种大语言模型!
256 1
|
机器人 Shell Android开发
Google Pixel 4 Android13 刷入Magisk + KernelSU 双root环境
Google Pixel 4 Android13 刷入Magisk + KernelSU 双root环境
1552 0
|
消息中间件 存储 自然语言处理
图解 Google V8 # 09:运行时环境:运行JavaScript代码的基石
图解 Google V8 # 09:运行时环境:运行JavaScript代码的基石
290 0
图解 Google V8 # 09:运行时环境:运行JavaScript代码的基石
|
算法 Android开发 开发者
被 Google Play “判定”违反政策:开源软件 FairEmail 开发者一怒之下关停所有项目
被 Google Play “判定”违反政策:开源软件 FairEmail 开发者一怒之下关停所有项目
240 0
被 Google Play “判定”违反政策:开源软件 FairEmail 开发者一怒之下关停所有项目
DHL
|
缓存 前端开发 算法
Google 推荐在项目中使用 sealed 和 RemoteMediator
这篇文章是对神奇宝贝(PokemonGo) 的部分功能做全面的分析
DHL
317 0
Google 推荐在项目中使用 sealed 和 RemoteMediator
|
知识图谱 ice
Google Earth Engine——美国国家环境预测中心(NCEP)的气候预测系统再分析(CFSR)是作为一个全球性的、高分辨率的、大气-海洋-陆地表面-海冰耦合系统设计和执行的数据集
Google Earth Engine——美国国家环境预测中心(NCEP)的气候预测系统再分析(CFSR)是作为一个全球性的、高分辨率的、大气-海洋-陆地表面-海冰耦合系统设计和执行的数据集
791 0
Google Earth Engine——美国国家环境预测中心(NCEP)的气候预测系统再分析(CFSR)是作为一个全球性的、高分辨率的、大气-海洋-陆地表面-海冰耦合系统设计和执行的数据集
|
编解码
Google Earth Engine——真彩色数据集Planet labs Inc. SkySat卫星在2015年为实验性的 “Skybox for Good Beta “项目,以及各种危机应对事件
Google Earth Engine——真彩色数据集Planet labs Inc. SkySat卫星在2015年为实验性的 “Skybox for Good Beta “项目,以及各种危机应对事件
397 0
Google Earth Engine——真彩色数据集Planet labs Inc. SkySat卫星在2015年为实验性的 “Skybox for Good Beta “项目,以及各种危机应对事件
|
传感器 定位技术 ice
Google Earth Engine——该数据集是美国宇航局在研究环境中使用地球系统数据记录 (MEaSUREs) 计划的一部分,包括选定冰川出口区域的月平均速度图
Google Earth Engine——该数据集是美国宇航局在研究环境中使用地球系统数据记录 (MEaSUREs) 计划的一部分,包括选定冰川出口区域的月平均速度图
146 0
Google Earth Engine——该数据集是美国宇航局在研究环境中使用地球系统数据记录 (MEaSUREs) 计划的一部分,包括选定冰川出口区域的月平均速度图
|
大数据 atlas
Google Earth Engine——流苏帽亮度(TCB)数据集该数据集由Malaria Atlas项目的Harry Gibson和Daniel Weiss制作
Google Earth Engine——流苏帽亮度(TCB)数据集该数据集由Malaria Atlas项目的Harry Gibson和Daniel Weiss制作
135 0
Google Earth Engine——流苏帽亮度(TCB)数据集该数据集由Malaria Atlas项目的Harry Gibson和Daniel Weiss制作