利用ssh实现前端自动化部署
1,在package.json新加命令
"publish-sit": "node build/publish.js sit",
"publish-prod": "node build/publish.js prod"
2,安装依赖
npm install ssh2-sftp-client
3,在build里面新加publish.js
var dayjs = require('dayjs');
const Client = require('ssh2-sftp-client');
const node_ssh = require('node-ssh');
const path = require('path');
const sitArgList = [
{
remote: {
host: '',
username: '',
port: 0000,
password: ''
},
backupDir: '',
packageDir: '',
backupName: '' + dayjs().format('YYYY-MM-DD-HH-mm-ss'),
distDir: path.resolve(__dirname, '../dist')
}
];
const prodArgList = [
{
remote: {
host: '',
username: '',
port: 0000,
password: ''
},
backupDir: '',
packageDir: '',
backupName: '' + dayjs().format('YYYY-MM-DD-HH-mm-ss'),
distDir: path.resolve(__dirname, '../dist')
}
];
const argList = process.argv[2] === 'prod' ? prodArgList : sitArgList;
class Publish {
constructor(args) {
this.args = args;
this.sftp = new Client();
this.ssh = new node_ssh();
}
doPublish() {
this.initBackupDir();
}
initBackupDir() {
let _this = this;
this.sftp
.connect(this.args.remote)
.then(() => {
return _this.sftp.exists(this.args.backupDir);
})
.then(data => {
if (!data) {
console.log('没有备份文件夹,创建备份文件夹');
_this.sftp.mkdir(this.args.backupDir).then(() => {
_this.doBackUp();
});
} else {
console.log('备份文件夹已存在');
_this.doBackUp();
}
})
.catch(err => {
console.error('检查备份文件出现异常' + err.message);
_this.sftp.end();
});
}
doBackUp() {
let _this = this;
_this.sftp
.exists(this.args.packageDir)
.then(data => {
console.log('备份' + data);
console.log('源文件' + this.args.packageDir);
console.log('目标文件' + this.args.backupDir + this.args.backupName);
if (data === 'd') {
_this.sftp
.rename(this.args.packageDir, this.args.backupDir + this.args.backupName)
.then(() => {
console.log('备份成功');
_this.sftp.end();
_this.doUpload();
})
.catch(err => {
console.error('备份出现异常' + err.message);
_this.sftp.end();
});
} else {
_this.sftp.end();
_this.doUpload();
}
})
.catch(err => {
console.error('备份出现异常' + err.message);
_this.sftp.end();
});
}
doUpload() {
const failed = [];
const successful = [];
this.ssh
.connect(this.args.remote)
.then(res => {
console.log('开始上传====');
console.log('上传 源文件目录:' + this.args.distDir);
console.log('上传 目标文件目录:' + this.args.packageDir);
this.ssh
.putDirectory(this.args.distDir, this.args.packageDir, {
recursive: true,
concurrency: 1,
validate: function (itemPath) {
return true;
},
tick: function (localPath, remotePath, error) {
if (error) {
failed.push(localPath);
} else {
successful.push(localPath);
}
}
})
.then(status => {
console.log('上传结束====' + status ? 'successful' : 'unsuccessful');
if (failed.length > 0) console.error('上传失败的列表为:\n', failed.join(', \n'));
if (successful.length > 0) console.log('上传成功的列表为:\n', successful.join(', \n'));
this.ssh.dispose();
})
.catch(err => {
console.log('上传出现异常:' + err.stack);
this.ssh.dispose();
});
})
.catch(err => {
console.error('上传出现异常' + err.message);
this.ssh.dispose();
});
}
}
for (let i = 0; i < argList.length; i++) {
let arg = argList[i];
let publish = new Publish(arg);
publish.doPublish();
}
4,更新部署路径,账号,密码,备份路径
5,npm run build 后 npm run publish-sit或者npm run publish-prod径