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();
})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM