preface

If you are not using the front-end automatic build integration tool, and are struggling to upload using SFTP after each package, the following simple automatic integration tool may be of interest to you.

Analysis of the

The SFTP tool process is as follows:Process for replacing SFTP with Node-SSH:Specific implementation process:

design

Next we built a package publishing tool, which I called publish-tools. For security and versatility, put the configuration file (publish.config.js) in the project as an NPM package command-line tool.

tool

  • Chalk // Font color tool
  • Commander // Command line tools
  • Inquirer // Interactive command-line tool
  • Node-ssh // Node-ssh tool
  • Ora // animation tool
  • Glob // File matching tool

Writing configuration files

Example of configuring two test environments (dev,dev2)

  1. You can choose to pack and release 2 test environments;
  2. You can view the packaging log;

It can be designed like this:

 module.exports = {

    option: {

        dev: {

        remoteDir' '.// Server address

        host' '.

        username' '.

        passdword' '.

        script` `.// Run the package command NPM run build

        localDir' ' // Dist /dev

        },

        dev2: {

        remoteDir' '.

        host' '.

        username' '.

        passdword' '.

        script' '.

        localDir' '

        }

    },

    logsfalse   / / log

    }

Copy the code

Write the NPM package

Initial Configuration

  1. Perform NPM init

  2. Name: the publish – tools

  3. Add to package.json

 "bin": { // Command name: file name

    "publishTest""./index.js"

  },

Copy the code
  1. Download the dependent
yarn add chalk commander inquirer node-ssh ora glob

Copy the code

The development of

1. Create the index.js file

2. Add #! At the top of the file. /usr/bin/env node

#! /usr/bin/env node

const path = require("path");

const program = require("commander");

const child_process = require("child_process");

const util = require("util");

const chalk = require('chalk');

const inquirer = require("inquirer");

const process = require("process");

const pka = require("./package.json");

const ora = require("ora");

const glob = require("glob");

const { NodeSSH } = require("node-ssh");

const ssh = new NodeSSH();

const exec = util.promisify(child_process.exec); // Execute shell commands using child processes

const arr = glob.sync(`${process.cwd()}/publish.config.js`); // Load the configuration file for the working directory

Copy the code

Note: File newline is changed to LF to prevent unnecessary errors

3. Determine the configuration file

 function log(str, color = 'white'{

        console.log(chalk[color](str))

    }

  function checkConf(cos{

  const target = ["remoteDir"."host"."username"."passdword"."script"."localDir"];

    if(! cos) {

        log(Missing argument option 'in'."red");

        return false

      }

      let flag = true

    for (let item in cos) {

      const arr = Object.keys(cos[item]);

      target.forEach((e) = > {

        if (arr.indexOf(e) == - 1) {

          log(`${item}Missing arguments in${e}`."red");

          flag= false;

        }

      });

    }

    // console.log(cos)

    return flag;

  }

let config = null// Config file

let types = []; // Interactive command selection

let pointLog = false// Whether to print logs

if (arr.length) {

  const src = arr[0];

  const { option, logs } = require(src);

  if (option) config = option;

  if (logs) pointLog = logs;

  if(! checkConf(config)) {

    return;

  } else {

    types = Object.keys(config);

  }

else {

  log(`${process.cwd()}Did not publish. Config. Js `."red");

  return;

}

if(! config || ! types.length)return;

Copy the code

4. Test the command line command in package.json

"scripts": {

    "test""node ./index.js publish" // equivalent to 'publishTest publish'

  }

Copy the code

Add index.js to the command line

program

  .version(pka.version, "-v, --version"// publishTest -v version number

  .option("publish, publish"."Local Packaged publishing tool"// publishTest publis => Executes the publish command

  .command("publish")

  .action( (a)= > { //publish the code executed by the command

  // Select the environment to publish

  });

  

  program.parse(process.argv);

Copy the code
  1. Select the environment to publish
 const { devType } = await inquirer.prompt([

      {

        name"devType".

        type"list".

        messagePlease select the test version to release.

        choices: types.filter((e) = > {  //dev,dev2

          return {

            name: e,

            value: e,

          };

        }),

        default: types[0].

      },

    ]);

    const selectConfig = config[devType]; // Select the configuration

    const spinner = ora("Start packing...");  / / animation

    spinner.start();

    pointLog && log(` configuration:The ${JSON.stringify(selectConfig, null.2)}`);

    pointLog && log('Execute command:${selectConfig.script}`);

    // Execute the local packaging command

Copy the code
  1. Execute the local packaging command
 exec(selectConfig.script, { encoding"utf8" }) // Execute the script in the configuration file

      .then((stdout, stderr) = > {

        if (pointLog) { // Package logs

          console.log(stdout);

          console.log(stderr);

        }

        spinner.succeed(); 

        // SSH connection to the server

        })

Copy the code
  1. Connecting to the server
//selectConfig => The selected configuration file

 ssh.connect({

            host: selectConfig.host,

            username: selectConfig.username,

            port: selectConfig.port || 22.

            password: selectConfig.passdword,

            tryKeyboardtrue.

          })

          .then( function ({

            log('Connected to the server successfully'."green");

            log('Start uploading files'."green");

          // Upload the file

          })

Copy the code
  1. Upload a file
//distDir: the local upload directory, remoteDir: the remote directory

ssh.putDirectory(distDir, selectConfig.remoteDir, { 

                  // Call back on file

                tickfunction (localPath, remotePath, error{

                  if (error) {

                    log(error, "red");

                  } else {

                    pointLog &&

                      log(` transfer:${localPath}  -> ${remotePath}`."green");

                  }

                },

              })

              .then(function ({

              // Upload succeeded

              })

Copy the code

At this point, the NPM package is complete. Now you can publish to NPM

npm login

npm who am i

npm publish

Local publishing success

conclusion

The above is the process of publish-tools, which has been published to NPM. If necessary, you can download and use it. We welcome your valuable comments and suggestions.