作为一个前端开发人员如果你只会写一些业务代码,从程序员的角度来考虑已经可以了。但是从架构的角度来考虑那远远不够;

在此记录下成长中的经历:

想要达成的目的:运行一个脚本实现代码的打包,上传至服务器并部署到服务器中;

服务端:需要安装pm2、nodejs;

在本地根目录下创建一个脚本文件名称自编自便;

1.下载需要依赖的包
npm i compressing ssh2 -S
//compressing 的作用是用来压缩文件的
//ssh2 的作用是用来连接服务器并执行操作的
2.创建操作的文件在根目录
2.1导入node的核心模块child_process
const {exec} = require('child_process')
2.2导入 compressing 压缩文件插件
const compressing = require('compressing')
2.3导入连接远程服务器的插件 ssh2
const Client = require('ssh2').Client;
2.4创建一个对象里面是服务器连接的属性
const server = {
host : '远程服务器的ip地址',
prot : 22, //默认的不用该如果没有修改过的话
username : '登陆远程服务器的用户名',
password : '登陆的用户名密码'
}
2.5创建一个ssh2的对象
const connect = new Client()
2.6在执行整个文件的时候让node创建一个子线程
/*第一个参数是要运行的命令,第二个参数是可选的如果有兴趣可以查看node官网的child_process.exec了解,第三个参数是是回调方法
在回调方法中有三个形参 error stdout stderr
如果成功 error 将会是null else error将会是Error实例
stdout和stderr参数将会包含子进程stdout和stderr输出
*/
const bat = exec('npm run build',(err,stdout,stderr)=>{
if (err) return console.log(`exec error: ${err}`);
console.log("打包成功");
//启动压缩方法
compress();
})
2.7在执行完打包子线程后就对打包好的文件进行压缩
function compress () {
console.log('*******压缩中*******');
//使用导入的compressing插件压缩我们需要的文件
//第一个参数是要压缩的文件夹,第二个参数是压缩过后的压缩包名称
compressing.zip.compressDir('dist/','dist.zip').then(()=>{
console.log('*****压缩成功*****');
// 成功之后就调用连接服务器的方法
conn();
})
}
2.8创建一个连接服务器的方法等压缩成功之后就调用
function conn () {
console.log('*****连接服务器******');
//使用前面定义好的ssh2对象
//ready 表示身份验证成功
//error 表示发生错误
//end 表示断开连接
//close 表示连接以关闭,如果这离是由于错误,hadError则设置为true
connect.on('ready',()=>{
  //在验证成功之后对文件进行上传操作
  upload()
 }).on('error',(err)=>{
  console.error(err)
  console.log('*****连接出错*****')
 }).on('end',()=>{
  console.log('*****连接关闭*****')
 }).on('close',(err)=>{
 if (err) return console.log('*****连接出错*****')
 }).connect(server)
//connect方法使用server里面的参数连接到服务器参数详情可查看ssh2-npm官网
}
2.9当ssh2验证完成之后就调用上传文件的方法
function upload () {
console.log('******开始上传******');
//开启一个sftp会话参数是个回调方法 回调方法有两个参数一个err实例,一个sftp实例
connect.sftp((err,sftp)=>{
if (err) throw err;
  //sftp的上传操作第一个参数是本地需要上传的文件路径,第二个参数是要将本地的文件上传到服务器的那个目录下
  sftp.fastPut('压缩好的文件名称','上传到服务器的目录',(err,res)=>{
  if (err) {
console.log('****上传失败*****');
console.error(err);
//如果发生错误就调用end方法断开连接
connect.end();
return;
  }
  //如果上传成功就调用解压文件的方法
   unzipShell()
})
})
}
2.10当文件上传成功之后就调用解压方法
function unzipShell() {
//在服务器上启动一个交互shell会话第一个参数是可选的,第二个参数是回调方法第一个是error实例第二个是shell会话流
connect.shell((err,stream)=>{
console.log('******解压中******');
if (err) throw err;
  let buf = "";
  //当会话检测到输出的时候嗲用close方法
  stream.on('close',err =>{
  //关闭连接
  connect.end();
  //如果失败就打印失败如果成功就答应成功
  if (err) return console.error(err);
  console.info('****** SUCCESS!! *******');
  }).on('data',data=>{
  //data是从stream.data事件接受的字符串块
  buf += data;
  console.log(buf)
  })
   //当解压完成后在终端中输入命令
   //(以下命令只是示范具体操作看你的项目)
   //1.到上传的目录下取并且解压上传的文件
   //2.cd 到解压后的文件夹里面 将文件夹里面的所有东西复制到上一层
  //3.到上一层目录中删除掉压缩文件和解压过后的文件夹
  //4.cd 到最上层 并且使用pm2托管node服务
  stream.write('cd 上传的文件夹路径 && unzip 压缩的文件名称 \nnext\n');
   stream.write('cd 解压后的文件夹下面 && /bin/cp -r -f * ../ \nnext\n');
  stream.write('cd ../ && rm -r -f dist && rm -r -f 压缩的文件名称 \nnext\n');
   stream.write('cd ../ && pm2 start nodemon server.js \nexit\n'); //server.js就是你需要启动的文件
})
}
3.在服务端的项目根目录中增加server.js文件我使用的是node服务托管文件
//导入node模块express
const express = require("express");
//创建一个服务
const app = express();
//将静态文件托管到本地服务中 文件名称不一定是dist
app.use(express.static("./dist"));
//启动一个服务在3000端口中
app.listen(3000,(err)=>{
if (err) return err;
console.log('server running at http://127.0.0.1:3000');
})

完成的代码

server.js是单独的需要手动创建和下面代码不关联

const {
exec
} = require("child_process");
const compressing = require("compressing");
const Client = require("ssh2").Client;
const server = {
host: '服务器ip',
port: 22,
username: '用户名',
password: '密码'
} const connect = new Client(); function conn() {
console.log('*******连接服务器***********');
connect.on('ready', () => {
upload();
}).on('error', (err) => {
console.error(err);
console.log('*****连接出错******')
}).on('end', () => {
console.log('*******连接关闭********')
}).on('close', (err) => {
if (err) throw err;
}).connect(server);
} function upload() {
console.log('******开始上传********');
connect.sftp((err, sftp) => {
if (err) throw err;
sftp.fastPut('./dist.zip', '/home/yunwo/dist/dist.zip', (err, res) => {
if (err) {
console.error(err);
console.log("*******上传失败******");
connect.end();
return;
}
unzipShell()
})
})
} function unzipShell() {
connect.shell((err, stream) => {
console.log('*******解压中*******');
if (err) throw err;
let buf = "";
stream.on('close', err => {
connect.end();
if (err) return console.error(err);
console.info('******** success!! *********');
}).on('data', data => {
buf += data;
console.log(buf);
})
stream.write('cd /home/yunwo/dist && unzip dist.zip \nnext\n');
stream.write('cd dist && /bin/cp -r -f * ../ \nnext\n');
stream.write('cd .. && rm -r -f dist && rm -r -f dist.zip \nnext\n');
stream.write('cd .. && pm2 start nodemon yunwoserver.js \nexit\n');
}) } function compress() {
console.log('******压缩中********');
compressing.zip.compressDir('dist/', 'dist.zip').then(() => {
console.log('******压缩成功******');
conn();
})
} console.log('*******打包中*******'); const bat = exec('npm run build', (err, stdout, stderr) => {
if (err) return console.error(`exec error : ${err}`);
console.log('********打包成功**********');
compress();
})

最新文章

  1. C#反射机制 Type类型
  2. 《BI那点儿事》数据流转换——导入列、导出列
  3. 优雅的设计单线程范围内的数据共享(ThreadLocal)
  4. Python学习笔记9—文件
  5. IO流 总结三
  6. js本地图片预览代码兼容所有浏览器
  7. Go 学习笔记(一)
  8. erp crm oa
  9. windows desktop.ini
  10. SWT的CheckBoxTreeView的上级菜单与下级菜单的选中的实现
  11. Counting Islands II
  12. android 学习 Spinner控件的使用
  13. spring boot / cloud (十五) 分布式调度中心进阶
  14. Material Design之NavigationView和DrawerLayout实现侧滑菜单栏
  15. ubuntu镜像下载地址
  16. flask之分页插件的使用、添加后保留原url搜索条件、单例模式
  17. vCenter机器查找功能不可用的解决
  18. CONFIG_DEBUG_USER【转】
  19. [UE4]蓝图节点的组织
  20. Swift5 语言参考(一) 关于语言参考

热门文章

  1. C语言学习书籍推荐《嗨翻C语言(英文)Head First C》下载
  2. plot3d网格读取写入与可视化
  3. SQL Server 存储过程相关语法
  4. zimg服务器图片数据迁移后,图片404异常的问题解决
  5. springcloud高可用方案
  6. Centos7 安装jdk,MySQL
  7. 20131214-HTML基础-第二十一天
  8. NET多线程之进程间同步锁Mutex
  9. 【排序函数讲解】sort-C++
  10. CF39D Cubical Planet-C++