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 后缀名判断限制代码
Mar 31 NodeJs
nodejs命令行参数处理模块commander使用实例
Sep 17 NodeJs
基于NodeJS的前后端分离的思考与实践(二)模版探索
Sep 26 NodeJs
Nodejs全局安装和本地安装的不同之处
Jul 04 NodeJs
Nodejs下DNS缓存问题浅析
Nov 16 NodeJs
nodejs学习笔记之路由
Mar 27 NodeJs
详解nodejs微信jssdk后端接口
May 25 NodeJs
NodeJS爬虫实例之糗事百科
Dec 14 NodeJs
解决Nodejs全局安装模块后找不到命令的问题
May 15 NodeJs
NodeJs项目中关闭ESLint的方法
Aug 09 NodeJs
nodejs aes 加解密实例
Oct 10 NodeJs
CentOS7中源码编译安装NodeJS的完整步骤
Oct 13 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
咖啡机如何保养和日常清洁?
2021/03/03 冲泡冲煮
百度站点地图(百度sitemap)生成方法分享
2014/01/09 PHP
php结合正则获取字符串中数字
2015/06/19 PHP
PHP使用curl制作简易百度搜索
2016/11/03 PHP
使用PHPWord生成word文档的方法详解
2019/06/06 PHP
安装docker和docker-compose实例详解
2019/07/30 PHP
jquery键盘事件使用介绍
2011/11/01 Javascript
jQuery的slideToggle方法实例
2013/05/07 Javascript
jQuery的显示和隐藏方法与css隐藏的样式对比
2013/10/18 Javascript
javascript利用apply和arguments复用方法
2013/11/25 Javascript
jQuery动态修改超链接地址的方法
2015/02/13 Javascript
javascript创建函数的20种方式汇总
2015/06/23 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
LayerClose弹窗关闭刷新方法
2018/08/17 Javascript
开源一个微信小程序仪表盘组件过程解析
2019/07/30 Javascript
Node配合WebSocket做多文件下载以及进度回传
2019/11/07 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
2020/02/05 Javascript
js最全的数组的降维5种办法(小结)
2020/04/28 Javascript
Vue绑定用户接口实现代码示例
2020/11/04 Javascript
Tensorflow中的placeholder和feed_dict的使用
2018/07/09 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
2020/10/15 Python
美国家用电器和电子产品商店:Abt
2016/09/06 全球购物
雅诗兰黛(Estee Lauder)英国官方网站:世界顶级化妆品牌
2016/12/29 全球购物
美国综合购物商城:UnbeatableSale.com
2018/11/28 全球购物
交通安全教育制度
2014/02/02 职场文书
幼儿园运动会入场词
2014/02/10 职场文书
班班通校本培训方案
2014/03/12 职场文书
投标文件签署授权委托书范本
2014/10/12 职场文书
2014年办公室个人工作总结
2014/11/12 职场文书
股权转让协议范本
2014/12/07 职场文书
专职安全员岗位职责
2015/04/11 职场文书
sql中mod()函数取余数的用法
2021/05/29 SQL Server
使用qt quick-ListView仿微信好友列表和聊天列表的示例代码
2021/06/13 Python
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
Python查找算法的实现 (线性、二分,分块、插值查找算法)
2022/04/24 Python