艺灵设计

全部文章
×

@vue/cli3项目开发之优化前端一键自动部署代码到服务器插件,支持上传到git仓库和备份解压

作者:艺灵设计 - 来源:http://www.yilingsj.com - 发布时间:2022-06-26 16:26:41 - 阅: - 评:0 - 积分:0

摘要:公司项目越来越多,需求也在不断变化,自己写的前端一键部署脚本也在不断的健壮更新中。为了避免明文密码泄露,我使用了密码文件的方案;为了防止服务器上文件误删除,我新增了可删除目录配置项;为了实现正式环境代码上传到另一个git仓库中,我又新增了git脚本;为了节省打包后上传速度慢的问题,我使用了压缩包上传,并对服务器文件做了自动备份和解压;为了更好的维护插件,我把他上传到了npmjs仓库中......

话说去年6月初的这个时候,艺灵分享了一篇关于前端一键部署代码到服务器的小插件。3个月后又添加了上传成功后自动播放音乐的功能,见文章→→→前端一键部署代码到服务器并播放音乐。如今一年过去,自己又根据业务做了些完善和调整,现将最新功能分享给有需要的看官。

一、优化明文密码

密码作为敏感项,理论上不应该用明文显示,因为这样太不安全了,一不小心被他人轻松登录了服务器岂不是很尴尬?!所以我们需要做一些处理,那不用明文该如何处理呢?考虑到密钥是一个文件,所以这里我们也可以借鉴密钥的方式,把密码放到一个文件中,然后用路径来引入密码文件。

1.1、把密码放在非项目下的磁盘文件中

这里需要注意几个地方:

1、存储密码的文件不建议放在项目中,避免手抖上传到了git仓库或被他人直接利用
2、密码处设置成文件地址后,所以要借助fs进行读取密码

1.2、代码实现

在项目根目录下创建一个名为keyUpload.js的文件,代码内容如下:

#!/usr/bin/env node
/*
 * @Description: 使用密码文件连接服务器
 * @Author: yilingsj(315800015@qq.com)
 * @Date: 2021-06-05 14:44:12
 * @LastEditors: yilingsj(315800015@qq.com)
 * @LastEditTime: 2021-06-05 15:14:22
 */
const Client = require('ssh2-sftp-client'); // 用于连接服务器
const fs = require('fs'); // 用于读取文件
const sftp = new Client();
const password = 'D:\\2022\\xxx\\password\\password.txt' // 本地密码文件地址(需要自己创建的哈),里面放你的密码。

sftp.connect({
  host: 'ip地址', // 服务器地址,修改成自己的
  port: '22', // 端口号,修改成自己的
  username: 'root', // 服务器登录用户名,修改成自己的
  password: fs.readFileSync(password) // 读取密码文件中的密码
}).then(() => {
  console.log('-连接服务器成功', Date.now());
}).then(data => {
  console.log(data, 'the data info');
  sftp.end();
}).catch(err => {
  console.log(err, 'catch error');
  sftp.end();
});

这样一来,即使我们的这个keyUpload.js脚本文件不小心被别人看到了,他也不知道我们的密码是多少哈。如果看官连porthostunsername这些信息也不想让别人看到,可以采取同样的做法把敏感信息做下处理。

二、优化服务器上要删除的目录

在前面的代码中,我们通过设置isRemoveRemoteFiletrue来实现对网站根目录中的文件进行删除,这个有些太暴力了。因为一般情况下,网站根目录下还有一些建站文件。比如:.htaccess(Apache用户配置文件(伪静态))、robots.txt(爬虫协议)、sitemap.xml(网站地图)、.user.ini(防止跨站攻击)、.well-known(一键申请SSL证书验证目录)等等。所以对于我们在删除时要有针对性。

2.1、精确删除目录

查看打包后的文件可以看到有cssjsstatic这3个文件夹,所以我们只删除这3个文件夹就行了。

if (config[NODE_ENV].isRemoveRemoteFile) {
  return deleteWebDir()
}
if (config[NODE_ENV].isRemoveRemoteFile) {
  const deleteWebDirList = ['/css', '/js', '/static']
  // 遍历删除指定目录,防止误删除其他文件
  for (var i = 0; i < deleteWebDirList.length; i++) {
    await deleteWebDir(config[NODE_ENV].webDir + deleteWebDirList[i])
  }
  console.log('-指定目录', deleteWebDirList, chalk.yellowBright('删除完毕'), Date.now())
}

现在,麻麻再也不用担心脚本会误删除服务器上的目录了。

三、新增:将打包代码上传git仓库的功能

由于业务的特殊性,dev开发环境、test测试环境、pre预上线环境都是直接把打包后的上传到服务器上,而prod正式环境是要把打包后的代码上传到另一个git仓库中。所以,在早期我都是等打包完成后手动复制代码到git仓库,然后再用sourcetree推送代码。这种做法非常浪费时间和人力,于是,我又写了一个小脚本工具,实现了这个功能。

3.1、git提交的一些步骤

通常情况下,提供本地代码到仓库需要以下步骤。

git checkout branch  // 切换分支
git pull  // 拉代码
git status  // 查看仓库当前状态
git add  // 把本地有修改的文件加入暂存区
git commit -m  // 将暂存区的内容添加到仓库中
git push  // 上传远程代码并合并

3.2、核心方法

即使是做成插件,同样需要上面这些步骤,只不过是让命令代替人工按顺序执行而已。

/**
 * @author: yilingsj(315800015@qq.com)
 * @description: 运行任务
 * @param {*}
 * @return {*}
 * @Date: 2021-09-25 09:47:15
 */
async function runTask() {
  await checkPackageJson() // 检查配置文件是否存在
  await findBuildDir(gitDistPath) // 查看仓库目录是否存在
  await deleteDir(dirList) // 删除仓库目录下的指定文件
  await compileDist() // 打包完成
  await findBuildDir(distPath) // 查看打包目录是否存在
  await gitPull() // 拉代码
  await copyDir() // 复制打包目录到仓库
  await gitStatus() // 查看仓库当前状态
  await gitAdd() // 把本地有修改的文件加入暂存区
  await gitCommit() // 将暂存区的内容添加到仓库中
  await gitPush() // 上传远程代码并合并
}
// 调用
runTask()

由于代码过长,此处就不再展示。有需要的看官可以通过文章末尾的仓库来查看完整源码。

四、新增:上传压缩包到服务器并实现备份和解压的功能

项目小的话,实际上是没必要把代码打包成压缩包后上传的。但我们的项目大啊,经过一系列的优化后,打成压缩包后体积仍大于20MB,用普通的上传方式真的很慢!

为了解决慢的问题,我尝试上传压缩包到服务器,还别说,上传效果是立竿见影!于是,我又实现了上传压缩包到服务器进行备份和解压的功能

关于这个备份和解压,如果方法对了,实现起来很简单,方法不对,那就是纯浪费时间!

4.1、小插曲:实现压缩包上传和解压并不容易

之前一直是使用ssh2-sftp-client这个npm包来连接服务器并实现上传操作,但这个npm包也是有缺点的。那就是:能上传压缩包,但无法执行shell脚本命令进行解压

不能解压,这就比较尴尬了。总不能我再登录服务器,然后手动解压吧!那这个工作效率仍然很低下啊!

我又去ssh2-sftp-client这个仓库上看了几遍,也在网上搜索了好久,最终确定这个插件是不支持shell命令的。既然这个插件不支持,那我就换个插件吧。

几经搜索,终于发现了ssh2这个仓库。既支持密码登录又支持密钥登录,周下载量也超过ssh2-sftp-client,最最最关键的是还支持shell命令!这简直就是我想要的啊!二话不说,npm install ssh2 --save-dev回车走你。

简单修改了下自己的脚本,尝试了下连接情况,密码密钥均可登录。又尝试了下上传压缩包到服务器,能上传成功且速度很快。现在只剩下解压刚上传的压缩包这一件事情了。

const { Client } = require('ssh2')
const sftp = new Client()
const connectSSh = async (distPath) => {
  sftp.connect(config[NODE_ENV]).on('ready', () => {
    console.log('连接成功', Date.now())
    sftp.sftp((err, SFTP) => {
      // 上传文件
      const startTime = Date.now()
      const zip = '/dist/dev/dist.tar.gz' // 本地压缩包地址
      const name = 'dist' + Date.now() + '.tar.gz'
      const webZip = config[NODE_ENV].dataBackup + '/' + name // 线上备份地址
      SFTP.fastPut(zip, webZip, {}, (err) => {
        if (err) {
          sftp.end()
        }
        // 上传完成后开始解压
        const cmd = `
        cd ${config[NODE_ENV].dataBackup}/
        tar -zxvf ${name} -C ${config[NODE_ENV].webDir}/
        exit`
        // 方法二
        sftp.exec(cmd, (err, SFTP) => {
          if (err) {
            shell.echo(chalk.yellowBright('解压失败'), cmd, Date.now())
            sftp.end()
          }
          SFTP.on('data', (data) => {}).on('close', () => {
            shell.echo('---解压完成' + chalk.greenBright('耗时'), chalk.magentaBright(Date.now() - startTime), 'ms')
            playMusic(config.musicDir) // 播放本地音乐
            sftp.end()
          })
        })
      })
    })
  })
}

当音乐响起时,用winScp连接服务器查看对应的目录,发现解压正常。

截止目前为止,这个插件已经覆盖了公司中大大小小的项目,确实帮助我节省了不少上传时间。如果看官您也面临我说的这些问题,不妨使用一下我的插件哦!

五、源码下载

为了方便维护插件和日后更新,这几天我又将其制作成了npm包并上传到了npmjs仓库中。现在看官可以更便捷的使用这个插件了,仓库首页的README中有非常详细的说明文档。如果您觉得这个插件帮助到了您,请不要吝啬小手手,帮忙点个star呗^v^!

npm库地址:https://www.npmjs.com/package/key-upload
github下载:https://github.com/yilingsj/key-upload
转载声明:
  若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:/xwzj/2022-06-26/key-upload-tar.html

若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。

亲,扫个码支持一下艺灵呗~
如果您觉得本文的内容对您有所帮助,您可以用支付宝打赏下艺灵哦!

Tag: @vue/cli3 vue脚手架 git tar ssh2 ssh2-sftp-client 前端 一键部署 服务器

上一篇: 记一次成功把Vue2后台项目改造成Vite2的踩坑经历   下一篇: 前端一键部署服务器方案key-upload

评论区