【日常记录】【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 node

console.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 node

console.log("hello world!");
console.log(process.argv);

在这里插入图片描述

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

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

npm i commander
#!/usr/bin/env node

const 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序 UI 风格,构建美妙视觉

小程序 UI 风格&#xff0c;构建美妙视觉

Prometheus写入influxDB:中间件remote_storage_adapter

Prometheus写入influxDB&#xff1a;中间件remote_storage_adapter prometheus默认采用的是本地磁盘做数据存储&#xff0c;本地存储的优势就是运维简单但是缺点就是无法海量的metrics持久化和数据存在丢失的风险,数据写入可能造成wal文件损坏导致采集数据无法再写入的问题。 …

使用Zed 实现测距

目录 1. 导入相关库 2. 相机初始化设置 3. 获取中心点深度数据 4. 计算中心点深度值 5. 完整代码 此代码基于官方代码基础上进行改写,主要是获取zed相机深度画面中心点的深度值,为yolo测距打基础。 Zed相机是由Stereolabs公司开发的一种先进的立体视觉相机。这种相机专…

openstack删除实例卡死在正在删除中

删除实例 问题描述解决办法 实验环境&#xff1b;服务器&#xff0c;openstackY版 问题描述 openstack在删除实例时一直显示正在删除中 解决办法 进入数据库修改实例状态&#xff0c;修改为错误&#xff0c;然后重新删除 首先查看对应实例id 进入数据库修改 rootcompute:~…

wx群发机器人.使用指南.

1.打开权限 1.打开下方Dock中 系统偏好设置 2.打开 安全性与隐私 3.打开 辅助功能 4.添加 终端 2.使用指南 1.下载 通讯录-联系人/群聊 1.先打开微信mac版,再打开群发机器人 2.点击下载 3.下载过程中,请不要操作键盘,鼠标 4.中途需停止可将鼠标放置左上角. 5.下载完成后文件…

vivado HW_TARGET

HW_目标 描述 硬件目标hw_target是包含一个或多个JTAG链的系统板 Xilinx FPGA设备&#xff0c;您可以使用比特流文件进行编程&#xff0c;或用于调试您的设计。 系统板上的硬件目标与Vivado Design Suite之间的连接 由硬件服务器对象hw_server管理。 使用open_hw_target命令打开…

Python深度学习基于Tensorflow(16)基于Transformer的对话实例

文章目录 基础数据清洗数据生成词汇表定义分词器并制作数据集构建Transformer模型并训练模型推理 Tensorflow 的核心就是注意力机制&#xff0c;在之前详细的介绍过&#xff0c;具体可以看这个&#xff1a;Python深度学习基于Tensorflow&#xff08;9&#xff09;注意力机制_te…

Python 深度学习和机器学习的模型评估库之torchmetrics使用详解

概要 在深度学习和机器学习项目中,模型评估是一个至关重要的环节。为了准确地评估模型的性能,开发者通常需要计算各种指标(metrics),如准确率、精确率、召回率、F1 分数等。torchmetrics 是一个用于 PyTorch 的开源库,提供了一组方便且高效的评估指标计算工具。本文将详…

GIS之arcgis系列10:arcpy实现批量掩膜提取

按掩膜提取 (Spatial Analyst) 提取掩膜所定义区域内的相应栅格像元。 OutRas ExtractByMask(InRas1, InMsk1, "INSIDE") 使用情况 输入栅格中的其他属性&#xff08;若有的话&#xff09;将按照原样添加到输出栅格属性表。 根据所记录的属性&#xff0c;某些属性…

【Java并发编程之美 | 第一篇】并发编程线程基础

文章目录 1.并发编程线程基础1.1什么是线程和进程&#xff1f;1.2线程创建与运行1.2.1继承Thread类1.2.2实现Runnable接口1.2.3实现Callable接口&#xff08;与线程池搭配使用&#xff09;1.2.4小结 1.3线程常用方法1.3.1线程等待与通知1.3.2线程睡眠1.3.3让出CPU执行权1.3.4线…

EVS9329-ES驱动器EVS9329ES可议价

EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES步进电机按结构分类&#xff1a;步进电动机也叫脉冲电机&#xff0c;包括反应式步进电动…

Unity射击游戏开发教程:(27)创建带有百分比的状态栏

创建带有弹药数和推进器百分比的状态栏 在本文中,我将介绍如何创建带有分数和百分比文本的常规状态栏。 由于 Ammo Bar 将成为 UI 的一部分,因此我们需要向 Canvas 添加一个空的 GameObject 并将其重命名为 AmmoBar。我们需要一个文本和两个图像对象,它们是 AmmoBar 的父级。…

13- 函数的定义与使用+形参实参区分

13- 函数的定义与使用形参实参区分 文章目录 13- 函数的定义与使用形参实参区分一、函数的定义与使用1.1 函数的结构1. 函数头2. 函数体 1.2 示例代码例子 1&#xff1a;无参数和无返回值的函数例子 2&#xff1a;带参数和返回值的函数 1.3 函数的基本语法1.4 函数的使用示例例…

多点液位传感器如何实现连续液位检测

如今&#xff0c;随着液位传感器的不断发展与演进&#xff0c;多点液位传感器也应用而生&#xff0c;可以实现对液体在多个连续点位的精确检测与监控&#xff0c;在洗地机设备上&#xff0c;可以及时了解水量&#xff0c;避免水资源浪费等情况。 多点式光电液位传感器采用了先…

测试记录4:在windows wsl2上配置ubuntu20.04

1.下载ubuntu20.04 (1) 在microsoft store中下载ubuntu20.04 (2) 在powershell中检查ubuntu20.04 wsl --listwsl -l -v安装成功 2.安装界面 见测试记录3 3.安装必要的功能包 sudo apt install zip sudo apt install gedit4.安装ros2 wget http://fishros.com/install -O …

提升你的编程体验:自定义 PyCharm 背景图片

首先&#xff0c;打开 PyCharm 的设置菜单&#xff0c;点击菜单栏中的 File > Settings 来访问设置&#xff0c;也可以通过快捷键 CtrlAItS 打开设置。 然后点击Appearance & Behavior > Appearance。 找到Background image...左键双击进入。 Image:传入自己需要设置…

蓝卓为中小制造企业注入数字化转型活力

随着劳动力成本上升,原材料价格上涨,企业生产成本逐年增加&#xff0c;市场竞争越来越激烈&#xff0c;传统的中小制造企业面临着巨大的压力。 通过数字化转型应对环境的变化已成为行业共识&#xff0c;在数字化的进程中&#xff0c;中小企业首要考虑生存问题&#xff0c;不能…

什么是场外期权?场外期权有几种做法?

今天带你了解什么是场外期权&#xff1f;场外期权有几种做法&#xff1f;期权分为场内期权&#xff0c;场外期权。场内期权我们都知道&#xff0c;是在期货盘里购买的期权&#xff0c;但场外期权呢&#xff1f; 什么是场外期权&#xff1f; 场外期权是一种在交易所之外进行交易…

数据结构和矩阵细节用法:double、cell和complex #matlab

矩阵建立 建立矩阵用[]&#xff1b; 矩阵的同一行内的元素用逗号或者空格隔开&#xff1b; 矩阵的不同行的元素用分号隔开 eg. 矩阵 A 1 2 3 4 5 6 7 8 9 在matlab中矩阵A表示为&#xff1a; clc;clear; A[1,2,3;4,5,6;7,8,9]; %或者A[1 2 3;4 5 …

helm升级部署时出现升级挂起状态处理

问题 在使用helm 升级命令时&#xff0c;升级命令如下&#xff1a; helm upgrade -i -f ./values-prod.yaml myapp ./ -n myns --create-namespace中途因为网络原因&#xff0c;再次运行上面升级命令时出现&#xff0c;如下错误&#xff1a; Error: UPGRADE FAILED: another …