nodejs利用readline提示输入内容实例代码


Posted in NodeJs onJuly 15, 2021

前言

最近进行小版本发包测试时忘记修改版本号了,进而想到在打包前提示输入版本号,然后把版本号打进版本说明内。最终效果为双击bat文件在终端内提示输入版本号,输入完成后保存版本号。

虽说批处理也可以做这事,但用js来写更得心应手点,故选用js处理。

过程分为四步

  • bat执行js
  • 终端提示输入版本号、执行打包命令
  • 修改版本号文件
  • gulp读取版本号json文件

简单来说是用bat文件触发打包命令进行打包。

1. bat执行js

首先创建两个文件buildVersion.bat、buildVersion.js。

buildVersion.bat中使用node运行js文件

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

%~dp0为当前目录。也可以在js后面传参数,如--buildType default

2. 终端提示输入版本号、执行打包命令

使用readline实现问答效果,再用child_process执行打包命令行。

进入buildVersion.js文件,先写简单的提示输入效果。

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
rl.question(`请输入新版本号: `, (name) => {

});

这样达不到效果。我们先显示之前的版本号,然后再提示输入新版本号,而且输入为空时沿用上次版本号。

// 获取版本信息,具体实现在第三步
var versionInfo;
const versionInfoUrl = './src/config/version/version.js';
function getVersion() {
    var buildVersion = "";
    try {
        versionInfo = require(versionInfoUrl);
        buildVersion = versionInfo.version;
    } catch (error) {

    }
    return buildVersion;
}

提示输入变成这样

const chalk = require('chalk');  // 引入颜色库
rl.question(`${chalk.cyan("当前版本号: ")}${chalk.bold.red(getVersion())} \n请输入新版本号: `, (name) => {
    !name && (name=versionInfo?versionInfo.version:"");
    console.log(`${chalk.cyan("新版本号是: ")}${chalk.bold.yellow(name)}`);

在终端上效果为

nodejs利用readline提示输入内容实例代码

有时版本号前会有固定前缀,我们在提示输入时把前缀显示出来,可以随意删除

// 写入默认值
rl.write("Version ")

接下来是运行打包命令。当前项目使用gulp打包。要在终端中显示gulp的提示信息,选用child_process.spawn

// 解析bat运行传入的参数
var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    string: ["name"]
});

const child_process = require('child_process');
rl.question(`${chalk.cyan("当前版本号: ")}${chalk.bold.red(getVersion())} \n请输入新版本号: `, (name) => {
    !name && (name=versionInfo?versionInfo.version:"");
    console.log(`${chalk.cyan("新版本号是: ")}${chalk.bold.yellow(name)}`);
    // 记录新版本号
    changeVersion(name);
    
    var buildType = argv.buildType || "build"  // 命令为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("-----------------  完成  --------------------"));
    });
});

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

在终端上效果为

nodejs利用readline提示输入内容实例代码

使用其他打包工具可以这样

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

3. 修改版本号文件

修改文件我想到的事用fs.writeFile写文件,但这样对json格式很好处理,对js文件处理很不方便。所以我把版本信息单独存在json文件中。创建两个文件version.js、version.json。

var VersionInfoJson;
// 考虑到可能会在html中引用,做了区分
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、用new obj.constructor ()构造函数新建一个空的对象,而不是使用{}或者[],这样可以保持原形链的继承;
// 2、用obj.hasOwnProperty(key)来判断属性是否来自原型链上,因为for..in..也会遍历其原型链上的可枚举属性。
// 3、上面的函数用到递归算法,在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。为了消除这种紧密耦合的现象,需要使用 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(); //保持继承链
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性
            var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
        }
    }
    return newObj;
}

function getNowFormatDate() {
    var date = new Date();
    var seperator1 = "-"; // 年月日间隔
    var seperator2 = ":"; // 时分秒间隔
    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读取版本号json文件

这一步就简单了。可以直接引用json。

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

也可以从gulp命令中拿到版本号。

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

console.log(argv.buildVersion)

做近一步的处理。

总结

到此这篇关于nodejs利用readline提示输入内容的文章就介绍到这了,更多相关nodejs readline提示输入内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

NodeJs 相关文章推荐
用nodejs实现PHP的print_r函数代码
Mar 14 NodeJs
NodeJS Express框架中处理404页面一个方式
May 28 NodeJs
Nodejs异步回调的优雅处理方法
Sep 25 NodeJs
Nodejs express框架一个工程中同时使用ejs模版和jade模版
Dec 28 NodeJs
nodeJS删除文件方法示例
Dec 25 NodeJs
NodeJS实现微信公众号关注后自动回复功能
May 31 NodeJs
NodeJS使用七牛云存储上传文件的方法
Jul 24 NodeJs
深入解析nodejs HTTP服务
Jul 25 NodeJs
nodejs实现超简单生成二维码的方法
Mar 17 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
May 15 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
NodeJS读取分析Nginx错误日志的方法
May 14 NodeJs
详解NodeJS模块化
NodeJs内存占用过高的排查实战记录
详解nodejs内置模块
May 06 #NodeJs
浅谈JS和Nodejs中的事件驱动
May 05 #NodeJs
ubuntu系统下使用pm2设置nodejs开机自启动的方法
May 12 #NodeJs
NodeJS和浏览器中this关键字的不同之处
Mar 03 #NodeJs
nodejs处理tcp连接的核心流程
Feb 26 #NodeJs
You might like
PHP缓冲区用法总结
2016/02/14 PHP
php实现用户登陆简单实例
2017/04/04 PHP
ThinkPHP 5.1 跨域配置方法
2019/10/11 PHP
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
2013/04/11 Javascript
jquery 实现返回顶部功能
2014/11/17 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
用JS生成UUID的方法实例
2016/03/30 Javascript
JavaScript实现输入框与清空按钮联动效果
2016/09/09 Javascript
jquery插件bootstrapValidator数据验证详解
2016/11/09 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
详解webpack + react + react-router 如何实现懒加载
2017/11/20 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
2017/11/20 Javascript
代码详解JS操作剪贴板
2018/02/11 Javascript
jquery层次选择器的介绍
2019/01/18 jQuery
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
跟老齐学Python之Import 模块
2014/10/13 Python
解析Python中的异常处理
2015/04/28 Python
解决python删除文件的权限错误问题
2018/04/24 Python
Python数据集切分实例
2018/12/08 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
2020/01/10 Python
pymysql 插入数据 转义处理方式
2020/03/02 Python
python手机号前7位归属地爬虫代码实例
2020/03/31 Python
网站开发实习生的自我评价
2013/12/11 职场文书
酒店管理毕业生自我鉴定
2014/03/02 职场文书
卖房授权委托书样本
2014/10/05 职场文书
部门2015年度工作总结
2015/04/29 职场文书
观看建国大业观后感
2015/06/01 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
升职感谢领导的话语及升职感谢信
2019/06/24 职场文书
python munch库的使用解析
2021/05/25 Python
简单介绍Python的第三方库yaml
2021/06/18 Python
python机器学习创建基于规则聊天机器人过程示例详解
2021/11/02 Python
聊聊SpringBoot自动装配的魔力
2021/11/17 Java/Android