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中利用Promise来封装异步函数
Feb 25 NodeJs
用nodejs搭建websocket服务器
Jan 23 NodeJs
Nodejs多站点切换Htpps协议详解及简单实例
Feb 23 NodeJs
详解nodeJS中读写文件方法的区别
Mar 06 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 NodeJs
NodeJs通过async/await处理异步的方法
Oct 09 NodeJs
Nodejs异步回调之异常处理实例分析
Jun 22 NodeJs
nodejs基础之多进程实例详解
Dec 27 NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 NodeJs
Nodejs 数组的队列以及forEach的应用详解
Feb 25 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+DBM的同学录程序(1)
2006/10/09 PHP
一个php生成16位随机数的代码(两种方法)
2014/09/16 PHP
CI框架中通过hook的方式实现简单的权限控制
2015/01/07 PHP
js 操作css实现代码
2009/06/11 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
2011/09/20 Javascript
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
2013/07/01 Javascript
父页面显示遮罩层弹出半透明状态的dialog
2014/03/04 Javascript
jQuery select自动选中功能实现方法分析
2016/11/28 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
three.js中文文档学习之创建场景
2017/11/20 Javascript
深入浅析Vue中的 computed 和 watch
2018/06/06 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
PHP实现基于Redis的MessageQueue队列封装操作示例
2019/02/02 Javascript
详解js中let与var声明变量的区别
2020/04/05 Javascript
微信小程序如何获取地址
2019/12/24 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
django1.8使用表单上传文件的实现方法
2016/11/04 Python
scrapy爬虫完整实例
2018/01/25 Python
Python数据可视化:泊松分布详解
2019/12/07 Python
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
MONNIER Frères英国官网:源自巴黎女士奢侈品配饰电商平台
2018/12/06 全球购物
加州风格的游泳和沙滩装品牌:Cupshe
2019/06/10 全球购物
合伙经营协议书范本
2014/09/13 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
高校自主招生校长推荐信
2015/03/23 职场文书
台风停课通知
2015/04/24 职场文书
股东大会通知
2015/04/24 职场文书
楚门的世界观后感
2015/06/03 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书
2016年禁毒宣传活动总结
2016/04/05 职场文书
html原生table实现合并单元格以及合并表头的示例代码
2023/05/07 HTML / CSS