Nodejs 技术栈下自研 Fire

前言

来啦老铁!

早先时候,我们在文章 Node.js 命令行工具库:js-fire 中一起学习了在 nodejs 技术栈下如何使用 js-fire 库,自动生成命令行接口,不过近期有遇到问题:

  • js-fire 不能像 Python 下的 Fire 模块链式使用多个方法,例如:
node .\test.js - add 2 3 - double

这种就不支持,作者的 README、代码和网上也都没有相关的办法,因此我萌生出一个想法:

  • 在 Nodejs 技术栈下自研 fire 功能;

学习路径

  1. 编写自研 fire 代码;
  2. 编写演示代码;
  3. 自研 fire 演示;
  4. 说明;

2. 编写自研 fire 代码;

代码如下:

(2024.04.29 更新,支持构造函数入参)

// 格式化入参,数字时使用数字而非纯文本,非数字使用纯文本格式
// 当数字长度过长时,也转为纯文本,避免失真,例如订单号:5596346346975032771
function formatParameter(parameter) {
    if (!parameter) {
        return;
    }
    return isNaN(parameter) ? `'${parameter}'` : (parameter.length > 15 ? `'${parameter}'` : parseFloat(parameter));
}

module.exports = async (
    // inputObject 这里指输入对象,即要 fire 的方法集对象
    inputObject,
    // 获取控制台输入,注意,入参顺序要按方法顺序来
    args = process.argv.slice(2),
) => {
    let executors = [];
    let params = [];

    // 设置构造参数
    if (args.indexOf("-") == -1) {
        console.error("请输入执行方法,以 - 分隔~");
        return;
    }
    let input;
    if (args.indexOf("-") > 0) {
        const constructorParams = args.splice(0, args.indexOf("-"));
        let params = [];
        for (let i = 0; i < constructorParams.length; i++) {
            params.push(constructorParams[i]);
        }
        input = eval(`new inputObject(${params.join(',')})`);
    } else {
        input = new inputObject();
    }

    // 组装其他方法
    args.reduce((accumulator, currentValue, index) => {
        // 根据命令行输入中的标识符 -,来决定方法名是哪个一个,这里使用 - 后面的第一个文本作为方法名
        // 使用两个 - 中间除去方法名的其他文本作为方法入参
        if (currentValue === '-') {
            const executorName = args[index + 1];
            params = [];
            executors.push({
                [executorName]: params
            });
            return accumulator;
        }
        // 如果当前是方法名,则不收集作为入参,否则进入下一步,搜集入参
        if (executors.find(jsonObject => currentValue in jsonObject) != undefined) {
            return accumulator;
        }
        // 收集两个 - 中间除去方法名的其他文本,以作为方法入参
        // 支持带 -- 的入参
        if (currentValue.startsWith("--") && currentValue.includes("=")) {
            currentValue = currentValue.split("=")[1];
        }
        params.push(currentValue);
        accumulator.push(currentValue);
        return accumulator;
    }, []);

    console.log(input.description);
    for (const executor of executors) {
        const executorName = Object.keys(executor)[0];
        // 拼装要执行的方法
        let params = [];
        let execText = "input[executorName](";
        executor[executorName].map((param) => {
            params.push(formatParameter(param));
            execText += `${formatParameter(param)},`;
        });
        execText += ")";
        // 使用 await 支持同步方法
        await eval(execText);
    }
};

1. 编写演示代码;

演示代码如下:
const config = require("./config");

const fire = require("./util/fire");

class demo {
    constructor() {
        this.description = "自研 Fire 工具演示";
        this.config = config;
    }

    add(number1, number2) {
        this.result = number1 + number2;
        return this.result;
    }

    double() {
        this.result = this.result * 2;
        return this.result;
    }

    printResult() {
        console.log("计算结果:", this.result);
        return "";
    }

    joinText(str1, str2) {
        this.str = str1 + "," + str2;
        return this.str;
    }

    printConfigItem() {
        console.log(this.config.name);
        // 用这个也行 console.log(config.name);
        return "";
    }
}

fire(new demo());

3. 自研 fire 演示;

  1. 单方法调用;
node .\test.js - add 2 3
演示-单方法调用
node .\test.js - joinText 1ab23 cd5f
非数学计算情况
  1. 多方法链式调用;
node .\test.js - add 2 3 - double - printResult
演示-多方法链式调用
  1. 演示文件中调用其他文件;
    例如,我的演示方法 printConfigItem 中,去读取其他文件中的配置信息 config.name;
node .\test.js - printConfigItem
调用其他文件

说明;

  1. 我这个 fire 工具只是快速实现版本,没有考虑太多,目前使用固定命令行格式调用,例如:
// 此处 2 代表 number1 的值,3 代表 number2 的值
node .\test.js - add 2 3 - double - printResult

或:

// 变量 --number1、--number2 得按顺序填写;
node .\test.js - add --number1=2 --number2=3 - double - printResult

后续会根据实际情况优化~

  1. 对代码没有严格的测试,有问题后续会修复更新,也欢迎读者帮忙指出,感谢~
  2. 对代码效率、风格等没有做严格的检查,如有不合适的地方,欢迎读者帮忙指出,感谢~

好了,今天就到这里了,继续搬砖了~

能力有限,欢迎指正、互相交流,感谢~

如果本文对您有帮助,麻烦点赞、关注!

感谢~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容