【日常记录】【node】从零开发一个node命令行工具

1、命令行工具

命令行工具(Cmmand Line Interface)简称cli,顾名思义就是在命令行终端中使用的工具。我们常用的 git 、npm、vim 等都是 cli 工具,比如我们可以通过 git clone 等命令简单把远程代码复制到本地。

再比如:vue的 vue-cli ;acro 的 arco-cli;vite的 npm create vite@latest ;nest 的 nest-cli等等

2、如何开发一个 node 命令行工具

2.1、初始化项目

  1. 创建一个文件夹,执行 npm 初始化命令
npm init -y
  1. 创建 src 文件夹,然后创建 index.js 文件,并写入以下代码
#!/usr/bin/env nodeconsole.log("hello world!");

里面的第一行代码,是告诉终端,这个文件要使用 node 去执行。具体含义需要百度了

2.2、本地创建命令

一般 cli都有一个特定的命令,比如 node、npm、pnpm、nest、arco 等等,所以我们也要给这个工具设置一个命令,比如 ncr

需要修改 package.json 文件 , 要加上 bin 这个属性,值是对象, 对象里面是 键值对 ,键是 命令名称,值是 入口文件路径

{"name": "ncr","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"bin": {"ncr": "./src/index.js"},"keywords": [],"author": "","license": "ISC"
}

然后 还需要再根目录执行一下 npm link , 有下面这个输出就对了

在这里插入图片描述

然后 终端 执行 ncr ,可以看到 hello world 就对了

在这里插入图片描述

2.3 实现获取版本信息命令 commander

如若再终端,输入 ncr -v --version ,我们想获取到 当前工具版本

先修改 src/index.js

#!/usr/bin/env nodeconsole.log("hello world!");
console.log(process.argv);

在这里插入图片描述

process.argv 这个属性的返回值,是数组,数组的第二项往后,就是 用户输入的命令

commander 这个库,可以解析命令行的参数,一般再开发命令行工具的时候,都会用这个

npm i commander
#!/usr/bin/env nodeconst pkg = require("../package.json");
const { program } = require("commander"); // 解析 命令行 参数的库// 设置 -h 选项的 用法
program.name("ncr").usage("[options]");
// program.version(pkg.version, "-v, --version", "获取 ncr 版本");// 添加选项
program.option("-v, --version", "获取 ncr 版本");
program.option("-h, --help", "获取帮助信息");// 处理选项
program.action(() => {let options = program.opts();console.log("option 获取");if (options.help) {console.log(`███╗   ██╗ ██████╗██████╗ ████╗  ██║██╔════╝██╔══██╗██╔██╗ ██║██║     ██████╔╝██║╚██╗██║██║     ██╔══██╗██║ ╚████║╚██████╗██║  ██║╚═╝  ╚═══╝ ╚═════╝╚═╝  ╚═╝
`);console.log(program.helpInformation());console.log("---------------------------------------------------------------------------------------");console.log("欢迎使用~~~~~");console.log("---------------------------------------------------------------------------------------");} else if (options.version) {console.log(chalk.blue.bgMagenta.bold(`当前版本号是: ${pkg.version}`));}
});

这个时候再终端输入 ncr -h 就会看到以下结果

在这里插入图片描述

Usage: index [options] 这一段也是可以修改的;Usage 就是用法的意思

program.name("ncr").usage("[options]");

在这里插入图片描述

2.4、终端输出增加颜色

需要用到 chalk 这个库

npm install chalk
const chalk = require("chalk"); // 让终端输出 增加一些样式
console.log(chalk.blue.bgMagenta.bold(`当前版本号是: ${pkg.version}`));

在这里插入图片描述

终端输入 ncr -v 终端报错

const chalk = require("chalk"); // 让终端输出 增加一些样式^Error [ERR_REQUIRE_ESM]: require() of ES Module F:\个人项目\ncr\node_modules\chalk\source\index.js from F:\个人项目\ncr\src\index.js not supported.
Instead change the require of F:\个人项目\ncr\node_modules\chalk\source\index.js in F:\个人项目\ncr\src\index.js to a dynamic import() which is available in all CommonJS modules.   at Object.<anonymous> (F:\个人项目\ncr\src\index.js:5:15) {code: 'ERR_REQUIRE_ESM'
}

在这里插入图片描述

如若出现这个错误,就降低 chalk的版本,换成 4 版本的

2.5、ncr current 命令 代码编写

// index.js
const { getRegistry } = require("./utils");program.command("current").description("查看当前npm镜像源").action(() => {console.log("当前npm镜像源是: " + chalk.blue.bgMagenta.bold(`${getRegistry()}`));});
// src/util/index.js
const { exec, execSync } = require("child_process"); //子线程用于执行shell命令exports.getRegistry = function () {// 默认返回 buffer 格式,return execSync("npm get registry", { encoding: "utf-8" });
};

在这里插入图片描述

2.6、ncr list 命令代码编写

registry.json

{"npm": {"registry": "https://registry.npmjs.org/","ping": "https://registry.npmjs.org/"},"yarn": {"registry": "https://registry.yarnpkg.com/","ping": "https://registry.yarnpkg.com/"},"taobao": {"registry": "https://registry.npmmirror.com/","ping": "https://registry.npmmirror.com/"}
}

// 查看所有的 npm 镜像源
const registryList = require("./registry.json");program.command("list").alias("ls") // 起个别名,也可以用 aliases方法,传递一个数组,设置多个别名.description("查看所有的npm镜像源").action(async () => {let curRegistry = getRegistry();Object.entries(registryList).forEach((f) => {console.log(// 一定要加 trim(f[1].registry.trim() === curRegistry.trim()? chalk.blue.bgMagenta.bold("*"): " ") +" " +f[0].padEnd(15, "-") +" " +f[1].registry);});});

2.7、ncr use 命令代码编写

切换源

// 使用某个 npm 镜像源const inquirer = require("inquirer"); // 交互式命令工具program.command("use").description("切换npm镜像源").action(() => {inquirer.prompt([{type: "list",name: "select",message: "请选择npm镜像源",choices: Object.keys(registryList).map((f) => f),},]).then((res) => {// res { select: 'yarn' }let registryUrl = registryList[res.select].registry;exec(`npm config set registry ${registryUrl}`,(error, stdout, stderr) => {if (error) {console.error(`exec error: ${error}`);return;}console.log("切换成功!");});});});

在这里插入图片描述

3、发布npm

先把npm的 registry 切换到官方的镜像源

npm login 先登录一下

然后 执行 npm publish

403 错误,大多数情况是 包的name 重名了

在这里插入图片描述

这样就是成功了!

总结

解析命令行的工具

  1. Yargs
  2. yargs-parser
  3. arg
  4. minimist
  5. commander

参考链接

  • chalk GitHub文档
  • inquirer GitHub文档
  • commander GitHub文档
  • node api

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache druid未授权命令执行漏洞复现

简介 Apache Druid是一个实时分析型数据库&#xff0c;旨在对大型数据集进行快速的查询分析&#xff08;"OLAP"查询)。Druid最常被当做数据库来用以支持实时摄取、高性能查询和高稳定运行的应用场景&#xff0c;同时&#xff0c;Druid也通常被用来助力分析型应用的图…

5款好用的轻量云服务器(618超便宜轻量云)

轻量云服务器是一种面向入门级用户和小型业务的云服务器产品&#xff0c;它们通常价格更实惠&#xff0c;管理起来也相对简单&#xff0c;以下是五款好用的轻量云服务器产品&#xff1a; 1.阿里云 优势&#xff1a;阿里云是国内最大的云服务提供商之一&#xff0c;拥有丰富的配…

BT音频方案

一、缩写 缩写 全程 释义 I2S I2S 音频传输接口总线 PCM Pulse-Code Modulation 基础音频数据或翻译为音频接口总线 HFP Handsfree 蓝牙通话协议 A2DP Advanced Audio Distribution Profile 蓝牙媒体音频协议 二、音频流转策略 蓝牙音频功能分为通话声音和媒体…

电脑数字键被锁住不能输入数字

情况: 反复点击数字键盘的NumLock,看它的灯是否能正常启动 1.如果NumLock灯可以正常的打开和关闭,并且无法输入内容 1.1打开控制面板 1.2 进入轻松使用中选择更改键盘的工作方式 1.3找到并点击设置鼠标键 1.4 赵到NumLock设置为关闭,然后确定即可

线性规划问题——单纯形算法

第一步&#xff1a;化“约束标准型” 在每个等式约束中至少有一个变量的系数为正&#xff0c;且这个变量只在该约束中出现。在每个约束方程中选择一个这样的变量称为基本变量。 剩下变量称为非基本变量。 一个简单的栗子 上图是一个约束标准型线性规划的例子。 等式1&#x…

理解查准率P、查全率R及Fβ度量怎么得来的

如果得到的是一组样本在两个算法上的一次预测结果&#xff0c;其中每个样本都被赋予了一个为正样本的概率&#xff08;例如&#xff0c;通过逻辑回归或朴素贝叶斯分类器得到的概率估计&#xff09;&#xff0c;那么可以通过改变不同的阈值点来利用这些预测结果画出PR曲线。 如果…

blender

通用设置: 仅显示/取消隐藏:数字键盘/移动视角:shift+鼠标中键Blender如何给场景添加参考图片-百度经验 (baidu.com)进入编辑模式:Tab编辑模式:点-线-面 反选:ctrl+按键重新计算面朝向:shift+n水密:+修改器:焊接连选的区别: 视窗设置 两个视图 …

Pytorch环境配置的方法

Pytorch虚拟环境配置全流程 以安装pytorch1.9.1为例 1. 创建虚拟环境 安装Anaconda3&#xff0c;打开 PowerShell 创建虚拟环境并进入&#xff1a; conda create -n torch1.9.1 python3.8 conda activate torch1.9.1 conda create -n torch1.9.1 python3.8 conda activate to…

错题记录(小测)

单选 错题1 错题2 错题3 代码题 反转链表 链表的回文结构

【LeetCode】4,寻找两个正序数组中的中位数

题目地址 B站那个官方解答视频实在看不懂&#xff0c;我就根据他那个代码和自己的理解写一篇文章 1. 基本思路 在只有一个有序数组的时候&#xff0c;中位数把数组分割成两个部分。中位数的定义&#xff1a;中位数&#xff0c;又称中点数&#xff0c;中值。中位数是按顺序排列…

消息队列的应用场景有哪些

通常来说&#xff0c;使用消息队列主要能为我们的系统带来下面三点好处&#xff1a; 异步处理 削峰/限流 降低系统耦合性 除了这三点之外&#xff0c;消息队列还有其他的一些应用场景&#xff0c;例如实现分布式事务、顺序保证和数据流处理。 异步处理 通过异步处理提高系…

计算机网络:网络层 - IPv4数据报 ICMP协议

计算机网络&#xff1a;网络层 - IPv4数据报 & ICMP协议 IPv4数据报[版本 : 首部长度 : 区分服务 : 总长度][标识 : 标志 : 片偏移][生存时间 : 协议 : 首部检验和][可变部分 : 填充字段] ICMP协议 IPv4数据报 一个IPv4数据报&#xff0c;由首部和数据两部分组成&#xff…

Python 越来越火爆

Python 越来越火爆 Python 在诞生之初&#xff0c;因为其功能不好&#xff0c;运转功率低&#xff0c;不支持多核&#xff0c;根本没有并发性可言&#xff0c;在计算功能不那么好的年代&#xff0c;一直没有火爆起来&#xff0c;甚至很多人根本不知道有这门语言。 随着时代的…

递归解析 LXML 树并避免重复进入某个节点

1、问题背景 我们在使用 LXML 库解析 MathML 表达式时&#xff0c;可能会遇到这样一个问题&#xff1a;在递归解析过程中&#xff0c;我们可能会重复进入同一个节点&#xff0c;导致解析结果不正确。例如&#xff0c;我们希望将以下 MathML 表达式解析为 Python 表达式&#x…

【数据结构初阶】--- 栈和队列

栈 栈的定义 栈&#xff1a;只允许在一端进行插入或删除的操作 事实上&#xff0c;线性表和链表都可以实现栈&#xff0c;但栈的特点更符合用顺序表实现 顺序表的队尾相当于栈顶&#xff0c;对栈放入数据&#xff0c;相当于顺序表的下标arr[index] x&#xff0c;而栈弹出数…

什么是无头浏览器以及其工作原理?

如果您对这个概念还不熟悉&#xff0c;那么使用无头网络浏览器的想法可能会让您感到不知所措。无头浏览器本质上与您熟悉的网络浏览器相同&#xff0c;但有一个关键区别&#xff1a;它们没有图形用户界面 (GUI)。这意味着没有按钮、选项卡、地址栏或视觉显示。 相反&#xff0c…

硬盘几个关键指标你一定要知道!

硬盘是数据中心中存储数据的重要部件&#xff0c;其关键指标影响硬盘的性能、可靠性和适用性。以下是一些常见的硬盘关键指标&#xff0c;并附上详细解释和举例&#xff1a; 容量&#xff08;Capacity&#xff09; 解释&#xff1a;硬盘的容量指其能存储数据的总量&#xff0c;…

CPN Tools学习——时间和队列【重要】

-Timed Color Sets 时间颜色集 -Token Stamps 令牌时间戳 -Event Clock 全局/事件/模拟时钟 -Time Delays on Transitions过渡的时间延迟 - List Color Set列表颜色集 - Queue排队 1.时间颜色集 在定时CPN模型令牌中有&#xff1a; &#xff08;1&#xff09;象征性的颜…

银河麒麟系统项目部署

使用服务器信息 软件&#xff1a;VMware Workstation Pro 虚拟机&#xff1a;ubtun 内存&#xff1a;20G 虚拟机连接工具&#xff1a; MobaXterm Redis连接工具&#xff1a; RedisDesktopManager 镜像&#xff1a;F:\Kylin-Server-10-8.2-Release-Build09-20211104-X86_64…

js: 百度云BOS 分片上传

百度云BOS存储后怎么查看或下载呢&#xff1f; // 1) 查看登录到百度智能云控制台 – 对象存储BOS”服务–选择一个Bucket&#xff0c;进入后可以查看该Bucket下的所有文件和文件夹。 2&#xff09;下载OS浏览器端不支持批量下载&#xff0c;可以通过以下方式下载文件(使用BOS桌…