node一键发布,并运行

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

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

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

服务端:需要安装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();
})

猜你喜欢

转载自www.cnblogs.com/HMleilei/p/11348243.html