Skip to main content

2 posts tagged with "chokidar"

View All Tags

· 4 min read
石晓波

CI&CD基础介绍

CI:持续集成,CD:持续交付和持续部署。现代软件开发的需求加上部署到不同基础设施的复杂性使得创建应⽤程序成为⼀个繁琐的过程。当应⽤程序出现规模性增⻓,开发团队⼈员变得更分散时,快速且不断地⽣产和发布软件的流程将会变得更加困难。为了解决这些问题,开发团队开始探索新的策略来使他们的构建、测试和发布流程⾃动化,以帮助其更快地部署新的⽣产。这就是持续交付和持续集成发展的由来。

持续集成(CI)是⼀个让开发⼈员将⼯作集成到共享分⽀中的过程,从⽽增强了协作开发。频繁的集成有助于解决隔离,减少每次提交的⼤⼩,以降低合并冲突的可能性。

手动实现一个简单的CI/CD

为了了解CI/CD的工作原理,让我们来实现一个简单的CI/CD。实现CI/CD需要借助于几个库chokidar 监听文件变化,shelljs执行shell命令。

index.js
const shell = require('shelljs');
const path = require('path');
const chokidar = require('chokidar')

const form = "./profile1.html*";
const to = "root@106.52.73.93";
const password = "1234567890";
const expectPath = path.join(__dirname, './expect.exp');

//const test = shell.exec('npm run test')
//if(test !== 0){
// process.exit(1);
//}

//const status = shell.exec('npm run build')
//if(status !== 0){
// process.exit(1);
//}

const watch = chokidar.watch(process.cwd())

//shell.exec(`scp ${form} ${to}`);


//加入expect.ecp
watcher.on('change', function(filePath){
shell.exec(`expect ${expectPath} ${filePath} ${to} ${password}`);
})

如上实现了基础的自动测试,自动编译打包和部署到服务器。但是在本机配置了免密登录的基础上才能正常运行否则执行scp命令的时候需要输入用户密码,阻塞自动化流程,并且所有的机器我们不一定有所有的控制权不可能给每台机器都配置免密登录,所以加入expect.exp可以监听到命令行密码的输入,可以命令的方式填入密码实现自动交互。

expect.exp
#!/usr/bin/expect
set from [lindex $argv 0]
set to [lindex $argv 1]
set password [lindex $argv 2]

set timeout 30
spawn bash -c "scp $from $to"

expect{
"*password:" {send "$password\r"}
}

interact

思考和优化点

如果有多台机器,如何实现动态部署到多台机器上?

答:可以使用数组保存from和to,循环遍历,将生产的结果文件使用scp命令部署到不同的机器。密码需要写入配置文件中,对密码配置文件使用加密保存。

如何读取超大日志文件?

答:使用stream+多线程处理

· 3 min read
石晓波

本地开发项目如果要实现内部部署测试,我们前端开发者每次都需要将打包后的文件交给后端开发人员,然后经过后端开发者部署到服务器。为了简化开发和减少交流成本,也为了提高前端开发者的位置,我们可以编写本地脚本自动化实现打包、测试、部署。也提高我们的工作效率。

如下是实现本地脚本自动化部署流程需要使用的包:

  • shelljs js执行shell脚本
  • rsync 使用 Node.js 构建和执行 rsync 命令的类。
  • colors
  • yargs
scripts/deploy.js
const shell = require('shelljs');
const Rsync = require('rsync');
const path = require('path');
const colors = require('colors');
const argv = require('yargs').argv;
const { exit } = require('process');

//获取执行的进程参数
const [targetName] = argv._;

//设置多台测试机,给每台测试机起代号,对应不同的IP
const host_map = {
staging001: 'onePiece:/root/build'
}

//判断如果不传参数 没有选择要部署的主机 给出提示
if (!host_map[targetName]) {
shell.echo("目标主机不存在!");
shell.exit(1);
}

//设置通知消息 以企业微信为例
function sendNotify(message) {
shell.exec(`curl 'https//qyapi.weixin.qq.com - H 'Content-type:application' - d '{"message": ${message}}`)
}

//0代表成功
// sendNotify('安装依赖')
// console.log(colors.yellow('☕️ 安装依赖'))
// if(shell.exec("npm install").code !== 0){
// shell.echo("error:npm install error.");
// shell.exit(1)
// }

//测试
// sendNotify('进行测试')
// console.log(colors.yellow('☕️ 进行测试'))
// if(shell.exec("npm run test").code !== 0){
// shell.echo("error:npm run test error.");
// shell.exit(1)
// }
//构建
sendNotify('开始构建')
console.log(colors.yellow('☕️ 开始构建'))
if(shell.exec("npm run build").code !== 0){
shell.echo("error:npm run build error.");
shell.exit(1)
}

//部署
sendNotify("开始部署")
console.log(colors.yellow('☕️ 开始部署'));
const rsync = Rsync.build({
source:path.join(__dirname,'../','/./build/*'),
destination: host_map[targetName],
flags:'avz',
shell:'ssh'
})

rsync.execute(function(error, code, cmd) {
console.log(error,code,cmd,)
console.log(colors.yellow('☕️ 部署完成'))
sendNotify('部署完成')
});

如上所示注释了安装依赖的步骤,本地开发环境不需要重新安装依赖,可以节省掉安装依赖的时间。需要注意的是建议配置免密登录,要不然需要手动输入密码体验差。

执行优化

如上要运行脚本需要使用node命令去执行对应的脚本文件,可以配置package.json的scripts

"scripts":{
"deploy": "node ./scripts/deploy.js"
}

扩展:也可以将本地脚本自动化部署写成npm包,通过配置主机的方式,命令执行部署