Nodejs uses readline to prompt for content input example code

Nodejs uses readline to prompt for content input example code

Preface

Recently, I forgot to change the version number when testing a small version. Then I thought of prompting for the version number before packaging, and then entering the version number into the version description. The final effect is that double-clicking the bat file will prompt you to enter the version number in the terminal, and the version number will be saved after entering.

Although batch processing can also do this, it is more convenient to write it in js, so js is chosen for processing.

The process is divided into four steps

  • bat execute js
  • The terminal prompts you to enter the version number and execute the packaging command
  • Modify the version number file
  • gulp reads the version number json file

Simply put, use bat file to trigger the packaging command for packaging.

1. bat executes js

First create two files buildVersion.bat and buildVersion.js.

Use node to run js file in buildVersion.bat

@echo off
set curpath=%~dp0
%curpath%nodejs\node.exe %curpath%buildVersion.js
pause

%~dp0 is the current directory. You can also pass parameters after js, such as --buildType default

2. The terminal prompts you to enter the version number and execute the packaging command

Use readline to achieve the question-and-answer effect, and then use child_process to execute the packaged command line.

Enter the buildVersion.js file and write a simple prompt input effect first.

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
rl.question(`Please enter the new version number: `, (name) => {

});

This will not achieve the desired effect. We first display the previous version number, then prompt for a new version number, and if the input is empty, the previous version number is used.

// Get version information, which is implemented in the third step var versionInfo;
const versionInfoUrl = './src/config/version/version.js';
function getVersion() {
    var buildVersion = "";
    try {
        versionInfo = require(versionInfoUrl);
        buildVersion = versionInfo.version;
    } catch (error) {

    }
    return buildVersion;
}

The prompt input becomes like this

const chalk = require('chalk'); // Import color library rl.question(`${chalk.cyan("Current version number: ")}${chalk.bold.red(getVersion())} \nPlease enter the new version number: `, (name) => {
    !name && (name=versionInfo?versionInfo.version:"");
    console.log(`${chalk.cyan("The new version number is: ")}${chalk.bold.yellow(name)}`);

The effect on the terminal is

Sometimes there is a fixed prefix before the version number. We display the prefix when prompting for input, and you can delete it at will.

// Write default value rl.write("Version")

The next step is to run the packaging command. The current project is packaged using gulp. To display gulp's prompt in the terminal, use child_process.spawn

// Parse the parameters passed in by bat operation var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    string: ["name"]
});

const child_process = require('child_process');
rl.question(`${chalk.cyan("Current version number: ")}${chalk.bold.red(getVersion())} \nPlease enter the new version number: `, (name) => {
    !name && (name=versionInfo?versionInfo.version:"");
    console.log(`${chalk.cyan("The new version number is: ")}${chalk.bold.yellow(name)}`);
    //Record the new version number changeVersion(name);
    
    var buildType = argv.buildType || "build" // The command is configured in gulp var gulpCmd = `gulp ${buildType} --buildVersion "${name}" --color --f ${__dirname}/gulpfile.js`;
    console.log(gulpCmd);
    let spawnProcess = child_process.spawn(gulpCmd, [], {
        shell: true
    });
    spawnProcess.stdout.on('data', (data) => {
        console.log(`${data.toString()}`);
    });
    spawnProcess.stderr.on('data', (data) => {
        console.log(`stderror: ${data}`);
    });
    spawnProcess.on('close', (code) => {
        if (code !== 0) {
            console.log(`close: $[code]`);
        }
    });
    spawnProcess.on('exit', (code) => {
        // console.log(`exit: ${code.toString()}`);
        console.log(chalk.bold.yellow("----------------- Completed --------------------"));
    });
});

function changeVersion(params) {
    if (versionInfo && versionInfo.changeVersion) {
        versionInfo.changeVersion(params);
    }
}

The effect on the terminal is

Using other packaging tools can be done like this

let exec = require('child_process').execSync;
exec('vue-cli-service --mode dev build', {
    stdio: 'inherit'
});

3. Modify the version number file

To modify the file, I thought of using fs.writeFile to write the file, but this is good for json format, but it is not convenient for js file processing. So I store the version information separately in a json file. Create two files: version.js and version.json.

var VersionInfoJson;
// Considering that it may be referenced in HTML, a distinction is made if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    getVersionInfo(true);
} else {
    if (typeof define === 'function' && define.amd) {
        getVersionInfo(false);
    } else {
        getVersionInfoLocal();
    }
}

function getVersionInfo(isModule) {
    try {
        VersionInfoJson = require("./version.json");
    } catch (error) {
        VersionInfoJson = {};
    }
    VersionInfoJson.buildTime = getNowFormatDate();
    VersionInfoJson.changeVersion = changeVersion;

    if (isModule) {
        module.exports = VersionInfoJson;
    }else{
        define([], function () {
            return VersionInfoJson;
        });
    }
}

async function getVersionInfoLocal() {
    try {
        VersionInfoJson = await getVersionJson();
    } catch (error) {
        VersionInfoJson = {};
    }
    VersionInfoJson.buildTime = getNowFormatDate();
    window.VersionInfo = VersionInfoJson;
}

function getVersionJson() {
    return new Promise((resolve, reject)=>{
        var request = new XMLHttpRequest();
        request.open("get", "config/version/version.json");
        request.send(null);
        request.onload = function () {
            if (request.status == 200) {
                var json = JSON.parse(request.responseText);
                resolve(json);
            }else{
                var json = {};
                resolve(json);
            }
        }
    });
}

function changeVersion(version) {
    var copyVersion = cloneObj(VersionInfoJson);
    copyVersion.version = version;
    if (copyVersion.hasOwnProperty("changeVersion")) {
        delete copyVersion["changeVersion"]
    }
    // console.log(copyVersion, __dirname, __filename)
    let fs = require('fs');
    fs.writeFile(__dirname + "/version.json", JSON.stringify(copyVersion), (err) => {

    });
}

// 1. Use new obj.constructor () to create an empty object instead of using {} or [], so as to maintain the inheritance of the prototype chain;
// 2. Use obj.hasOwnProperty(key) to determine whether the property comes from the prototype chain, because for..in.. will also traverse the enumerable properties on its prototype chain.
// 3. The above function uses a recursive algorithm. If the function has a name and the name will not change in the future, there is no problem with this definition. But the problem is that the execution of this function is tightly coupled to the function name factorial. To eliminate this tight coupling, use arguments.callee.
function cloneObj(obj) {
    if (obj === null) return null
    if (typeof obj !== 'object') return obj;
    if (obj.constructor === Date) return new Date(obj);
    if (obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor(); //keep the inheritance chain for (var key in obj) {
        if (obj.hasOwnProperty(key)) { //Do not traverse the properties on its prototype chain var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // Use arguments.callee to decouple from the function name}
    }
    return newObj;
}

function getNowFormatDate() {
    var date = new Date();
    var seperator1 = "-"; // year, month, day interval var seperator2 = ":"; // hour, minute, second interval var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate +
        " " + date.getHours() + seperator2 + date.getMinutes() +
        seperator2 + date.getSeconds();
    return currentdate;
}

4. gulp reads the version number json file

This step is easy. You can directly reference json.

const versionInfo = require('./src/config/version/version.js');

You can also get the version number from the gulp command.

var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    string: ["name"]
});

console.log(argv.buildVersion)

Take a closer look.

Summarize

This is the end of this article about nodejs using readline to prompt input content. For more related nodejs readline prompt input content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Node.js readline example of reading and writing file contents line by line
  • Node.js uses the readline module to implement input and output
  • Detailed explanation of the use of the readline module of Node.js
  • Node.js API detailed explanation of the readline module usage
  • Use of Node.js readline module and util module

<<:  vmware installation error VMware Workstation failed to start VMware Authorization Service

>>:  A practical record of restoring a MySQL Slave library

Recommend

How to quickly install RabbitMQ in Docker

1. Get the image #Specify the version that includ...

vue_drf implements SMS verification code

Table of contents 1. Demand 1. Demand 2. SDK para...

How to configure Nginx virtual host in CentOS 7.3

Experimental environment A minimally installed Ce...

Vue+axios sample code for uploading pictures and recognizing faces

Table of contents Axios Request Qs processing dat...

Differentiate between null value and empty character ('') in MySQL

In daily development, database addition, deletion...

How to completely uninstall node and npm on mac

npm uninstall sudo npm uninstall npm -g If you en...

Detailed explanation of basic operation commands for Linux network settings

Table of contents View network configuration View...

How to wrap HTML title attribute

When I was writing a program a few days ago, I wan...

Analysis of the Nesting Rules of XHTML Tags

In the XHTML language, we all know that the ul ta...