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命令行参数处理模块commander使用实例
Sep 17 NodeJs
详谈nodejs异步编程
Dec 04 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
简单好用的nodejs 爬虫框架分享
Mar 26 NodeJs
详解nodejs express下使用redis管理session
Apr 24 NodeJs
win系统下nodejs环境安装配置
May 04 NodeJs
详解NODEJS基于FFMPEG视频推流测试
Nov 17 NodeJs
nodejs发送http请求时遇到404长时间未响应的解决方法
Dec 10 NodeJs
NodeJS安装图文教程
Apr 19 NodeJs
Nodejs中获取当前函数被调用的行数及文件名详解
Dec 12 NodeJs
nodejs使用async模块同步执行的方法
Mar 02 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 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
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
php保存任意网络图片到服务器的方法
2015/04/14 PHP
PHP多维数组遍历方法(2种实现方法)
2015/12/10 PHP
ThinkPHP和UCenter接口冲突的解决方法
2016/07/25 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
2017/08/10 PHP
jQuery 使用手册(六)
2009/09/23 Javascript
11个用于提高排版水平的基于jquery的文字效果插件
2012/09/14 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
JavaScript常用本地对象小结
2016/03/28 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
js实现登录验证码
2016/12/22 Javascript
微信小程序 列表的上拉加载和下拉刷新的实现
2017/04/01 Javascript
全面解析jQuery中的$(window)与$(document)的用法区别
2017/08/15 jQuery
JavaScript实现三级级联特效
2017/11/05 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
2018/10/12 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
2019/01/28 Javascript
js中的面向对象之对象常见创建方法详解
2019/12/16 Javascript
javascript设计模式之迭代器模式
2020/01/30 Javascript
Python二维码生成库qrcode安装和使用示例
2014/12/16 Python
python获取点击的坐标画图形的方法
2019/07/09 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
深入了解Python 变量作用域
2020/07/24 Python
Python requests接口测试实现代码
2020/09/08 Python
HTML5 canvas基本绘图之文字渲染
2016/06/27 HTML / CSS
HTML5、Select下拉框右边加图标的实现代码(增进用户体验)
2017/10/16 HTML / CSS
怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回 指向字符的指针的函数的指针的数组?
2013/03/19 面试题
咖啡书吧创业计划书
2014/01/13 职场文书
公司外出活动方案
2014/08/14 职场文书
印刷技术专业自荐信
2014/09/18 职场文书
长城导游词
2015/01/30 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
借条格式范本
2015/05/25 职场文书
新郎新娘致辞
2015/07/31 职场文书
2019年公司卫生管理制度样本
2019/08/21 职场文书
python之PySide2安装使用及QT Designer UI设计案例教程
2021/07/26 Python