“This is the 10th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

This article focuses on the process of packaging and deploying a local project to a server by executing a script. Previous articles:

  • Javascript to write shell scripts a basic operation
  • Javascript write shell script 2 Execute Linux command
  • Javascript write shell script 3 to initiate network request

Package Deployment Process

The process is as follows:

  1. Run NPM run build locally
  2. The compressed file
  3. To the deployment server, which needs a path to the code
  4. Decompress and synchronize with the project deployment path
  5. Delete the file

The required dependencies are as follows:

  • Shelljs Executes shell scripts
  • Ssh2 Sends files
  • Chalk makes the output of the console colorable and not necessarily dependent

First install dependencies

npm i shelljs ssh2 chalk -D
Copy the code

Next, create a release file in the project root directory

In development, we often need to deploy the code to different servers, so we need to create a new SERVER object to store all the SERVER information

#! /usr/bin/env node

const SERVER={
    42: {
        host: '10.1.43.42'.port: 19222.username: 'xiaoming'.password: 'ababababa'.// The local directory of the code package to be sent, either absolute or relative
        distPath: 'dist'.// Remote server deployment path
        remoteBuildPath:
            '/home/admin/video-app/webpage'.// Temporarily store the code path
        remoteCodePath: '/home/diyvrbt/code'.buildScript: 'npm run build' // The default is NPM run build}},Copy the code

In the script, we determine which server to send based on user input

 // Get the parameters passed in and decide which server to send to
const [nodeEnv, dir, ...args] = process.argv
// If not, use the default server
const serverNo = args.length == 0 ? DEFAULT_SERVER : args[0]

if (!Object.keys(SERVER).includes(String(serverNo))) {
    throw new Error('Server does not exist')}Copy the code

Then run NPM run build and print the output folder into a compressed package

/ / packaging
shell.exec(buildScript)

// Compress the file
shell.exec(`tar -zcf ${localPath} ${appName}`)
Copy the code

Then use the SSH2 module to connect to the server and send the file

FastPut accepts four parameters

  • LocaPath Local path
  • RemotePath remotePath
  • config
  • Callback (err) Callback function

We do the rest of the logic in the callback function

The rsync command is used to synchronize files between two directories. This command synchronizes files between two directories, which is better than deleting files before moving them.

The complete code

#! /usr/bin/env node

// If there are multiple servers and no parameters are passed, specify a default server
const DEFAULT_SERVER=The '42'

const SERVER = {
    42: {
        host: '10.1.43.42'.port: 19222.username: 'xiaoming'.password: 'ababababa'.// The local directory of the code package to be sent, either absolute or relative
        distPath: 'dist'.// Remote server deployment path
        remoteBuildPath:
            '/home/admin/video-app/webpage'.// Temporarily store the code path
        remoteCodePath: '/home/diyvrbt/code'.buildScript: 'npm run build' // The default is NPM run build}}const shell = require('shelljs')
const Client = require('ssh2').Client
const dayjs = require('dayjs')
const chalk = require('chalk')

function getLastWord(str) {
    return str.split('/').pop()
}
function log(str) {
    console.log(chalk.blueBright(str))
}

/** * This script is used to send a file to a remote server * 1. Compress the file first * 2. Send it to the remote server * 3. Synchronize with the path of the deployed code * 4. Delete file */; (function() {
    // Get the parameters passed in and decide which server to send to
    const [nodeEnv, dir, ...args] = process.argv
    // If not, use the default server
    const serverNo = args.length == 0 ? DEFAULT_SERVER : args[0]

    if (!Object.keys(SERVER).includes(String(serverNo))) {
        throw new Error('Server does not exist')}const server = SERVER[serverNo]
    const {
        remoteBuildPath,
        remoteCodePath,
        distPath,
        buildScript = 'npm run build'
    } = server
    const appName = getLastWord(distPath)

    // Local directory
    const localPath = appName + '.tar.gz'
    // File name of the server
    const remoteDirName =
        appName + '_' + dayjs().format('YYYYMMDDTHHmmss') + '.tar.gz'
    // Server directory
    // Store the code directory

    const remotePath = `${remoteCodePath}/${remoteDirName}`
    log('Server information:The ${JSON.stringify(server)}Local directory:${localPath}Remote directory:${remotePath}
        `)

    const conn = new Client()
    // Delete the previous file

    / / packaging
    shell.exec(buildScript)

    // Compress the file
    shell.exec(`tar -zcf ${localPath} ${appName}`)

    // Connect to the server and send the file
    conn.on('ready'.() = > {
        log('Client::ready')
        // log(' SFT server connected, ready to transfer files ')
        conn.sftp((err, sftp) = > {
            log('SFTP connection successful')
            if (err) throw err

            sftp.fastPut(
                localPath,
                remotePath,
                {
                    chunkSize: 2000.concurrency: 64.step(total_transferred, chunk, total) {
                        // Print the progress
                        log(Math.floor((total_transferred / total) * 100) + The '%')}},err= > {
                    if (err) {
                        console.log('err', err)
                        conn.end()
                        return
                    }
                    // 1. Decompress the file. 2
                    const script = `
                    cd ${remoteCodePath} && 
                    pwd                  &&
					rm -rf ${appName}    &&
                    tar -zxf ${remoteDirName} &&
                    rsync -rtplze  --progress --stats ${appName}/ ${remoteBuildPath}  && 
                    rm ${remoteDirName}
                `
                    console.log('Command to execute after transferring the file:', script)

                    conn.exec(script, (err, stream) = > {
                        if (err) {
                            console.log(err)
                            return
                        }
                        stream
                            .on('close'.function(args) {
                                console.log('close', args)
                                if (args == 0) {
                                    log('success! ')
                                }
                                conn.end()
                            })
                            .on('data'.function(data) {
                                console.log('data', data.toString())
                            })
                    })
                }
            )
        })
    }).connect(server)
})()

Copy the code