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

Example code for Html layered box-shadow effect

First, let’s take a look at the picture: Today we...

An in-depth introduction to React refs

1. What is Refs is called Resilient File System (...

A brief analysis of the basic concepts of HTML web pages

What is a web page? The page displayed after the ...

Drawing fireworks effect of 2021 based on JS with source code download

This work uses the knowledge of front-end develop...

JavaScript implements large file upload processing

Many times when we process file uploads, such as ...

Tutorial on installing MYSQL5.7 from OEL7.6 source code

First, download the installation package from the...

How to add java startup command to tomcat service

My first server program I'm currently learnin...

You may need a large-screen digital scrolling effect like this

The large-screen digital scrolling effect comes f...

Detailed explanation of three methods of JS interception string

JS provides three methods for intercepting string...

MySQL slow query and query reconstruction method record

Preface What is a slow query and how to optimize ...

Demystifying the HTML 5 Working Draft

The World Wide Web Consortium (W3C) has released a...

Eight implementation solutions for cross-domain js front-end

Table of contents 1. jsonp cross-domain 2. docume...

Solution to the problem of mysql service starting but not connecting

The mysql service is started, but the connection ...

CSS modular solution

There are probably as many modular solutions for ...

javascript to switch pictures by clicking a button

This article example shares the specific code of ...