導入サーバをフロントエンドで自動化し、煩雑な導入プロセスに別れを告げる


永遠の前言
シンプルで実用的なフロントエンドの導入、1つのコマンドが完了し、煩雑なステップを省くことができます!主にnodejs shelljs(コマンドラインコマンド)node-ssh(接続サーバ)プロジェクトgitアドレス(このgitプロジェクトは私が自分で作った比較lowのvue足場で、tsを統合しています)(初めて文章を書いて、文章がだめで、多くのことを許して、間違っているところがありますが)
(主にuploadディレクトリへの自動配置を参照)
あなたのプロジェクトで使用する方法(五歩曲)
最初のステップは、プロジェクト内のuploadフォルダをプロジェクトルートディレクトリにコピーします.
ステップ2では、js関連依存をダウンロードします.
npmまたはcnpm i chalk ora shelljs node-ssh inquirer compressing-D
ステップ3でupload/configを開きます.jsプロファイル、sshアドレス、ユーザー名、検証方式、アップロードするディレクトリの構成
第四歩、あなたのプロジェクトでpackage.jsonファイルに「deploy」:「node./upload/upload.js」を追加
最後にコマンドラインにnpm run deployを入力してパブリッシュ環境を選択しojbk
大功成~~
主なファイルを見てjs
プロジェクト依存
const chalk = require('chalk') //     
const ora = require('ora') //       
const spinner_style = require('./spinner_style') //      
const shell = require('shelljs') //   shell  
const node_ssh = require('node-ssh') // ssh     
const inquirer = require('inquirer') //     
const zipFile = require('compressing')//   zip
const fs = require('fs') // nodejs      
const path = require('path') // nodejs      
const CONFIG = require('./config') //   

いくつかの定数、変数、logs
const SSH = new node_ssh();
let config; //      inquirer           |      

//logs
const defaultLog = log => console.log(chalk.blue(`---------------- ${log} ----------------`));
const errorLog = log => console.log(chalk.red(`---------------- ${log} ----------------`));
const successLog = log => console.log(chalk.green(`---------------- ${log} ----------------`));

//     
const distDir = path.resolve(__dirname, '../dist'); //   
const distZipPath = path.resolve(__dirname, `../dist.zip`);
//     (dist.zip    ,     ,    config    PATH   )

梱包する
まず、プロジェクトパッケージコマンドを実行します.
//       npm run build 
const compileDist = async () => {
  const loading = ora( defaultLog('      ') ).start();
  loading.spinner = spinner_style.arrow4;
  shell.cd(path.resolve(__dirname, '../'));
  const res = await shell.exec('npm run build'); //  shell     
  loading.stop();
  if(res.code === 0) {
    successLog('      !');
  } else {
    errorLog('      ,    !');
    process.exit(); //    
  }
}

あっしゅく
次に、パッケージ化されたコード/distディレクトリをパッケージ化します(distでない場合は、上のdisDir定数の末尾のdistを変更します).
//    
const zipDist = async ()=>{
  defaultLog('      ');
  try {
    await zipFile.zip.compressDir(distDir, distZipPath)
    successLog('    !');
  } catch (error) {
    errorLog(error);
    errorLog('    ,     !');
    process.exit(); //    
  }
}

接続サーバ
次にsshでサーバに接続するには、2つの方法があります.1つは鍵で接続(推奨)、2つはパスワードで接続します.
鍵接続には、ネイティブ公開鍵をサーバ指定ディレクトリに置く必要があります(upload/config.jsで説明あります)
//     
const connectSSH = async ()=>{
  const loading = ora( defaultLog('       ') ).start();
  loading.spinner = spinner_style.arrow4;
  try {
    await SSH.connect({
      host: config.SERVER_PATH,
      username: config.SSH_USER,
      // privateKey: config.PRIVATE_KEY, //    (  )    
      password: config.PASSWORD //         
    });
    successLog('SSH    !'); 
  } catch (error) {
    errorLog(error);
    errorLog('SSH    !');
    process.exit(); //    
  }
  loading.stop();
}

ファイルのアップロード
次にsshでオンラインコマンドを実行してターゲットディレクトリを空にし、zipをサーバにアップロードして解凍するなどの操作を行います.
//      
/**
 * 
 * @param {String} command        ls
 */
const runCommand = async (command)=> {
  const result = await SSH.exec(command, [], { cwd: config.PATH})
  // defaultLog(result);
}

//             
const clearOldFile = async () =>{
  const commands = ['ls', 'rm -rf *'];
  await Promise.all(commands.map(async (it)=>{
    return await runCommand(it);
  }));
}

//  zip      
const uploadZipBySSH = async () =>{
  //  ssh
  await connectSSH();
  //        
  await clearOldFile();
  const loading = ora( defaultLog('      ') ).start();
  loading.spinner = spinner_style.arrow4;
  try {
    await SSH.putFiles([{ local: distZipPath, remote: config.PATH + '/dist.zip' }]); //local    ; remote     ;
    successLog('    !'); 
    loading.text = '      ';
    await runCommand('unzip ./dist.zip'); //  
    await runCommand(`rm -rf ${config.PATH}/dist.zip`); //          
    //      dist             
    //             /test/html             ,             /test/html/dist  
    //    dist            /test/html ;       ,   /test/html/h5     /test/html/admin         
    await runCommand(`mv -f ${config.PATH}/dist/*  ${config.PATH}`); 
    await runCommand(`rm -rf ${config.PATH}/dist`); //      dist    
    SSH.dispose(); //    
  } catch (error) {
    errorLog(error);
    errorLog('    !');
    process.exit(); //    
  }
  loading.stop();
}

統合
これらを1つの関数に統合します
//------------    ---------------
const runUploadTask = async () => {
  console.log(chalk.yellow(`--------->           2020         

パブリッシュ前のチェック構成
//         
/**
 * 
 * @param {Object} conf     
 */
const checkConfig = (conf) =>{
  const checkArr = Object.entries(conf);
  checkArr.map(it=>{
    const key = it[0];
    if(key === 'PATH' && conf[key] === '/') { //  zip             
      errorLog('PATH          !'); 
      process.exit(); //    
    }
    if(!conf[key]) {
      errorLog(`    ${key}     `); 
      process.exit(); //    
    }
  })
}

パブリッシュ
インタラクティブ選択パブリケーション環境を実行し、パブリケーションプログラムを起動します.
//             
inquirer
  .prompt([{
    type: 'list',
    message: '       ',
    name: 'env',
    choices: [{
      name: '    ',
      value: 'development'
    },{
      name: '    ',
      value: 'production'
    }]
  }])
  .then(answers => {
    config = CONFIG[answers.env];
    checkConfig(config); //   
    runUploadTask(); //   
  });

大功を成し遂げる
の最後の部分
咳咳、安心して、公衆番号のどんな広告があることはできなくて、賞を求めることもできなくて、もしあなたに少し助けがあると思ったらいいですか?あるいはGitHubに行ってstarを注文したら、それはとても感謝します