构建优雅、高效的 Nodejs 命令行工具 - Archons

目录

    • 项目简介
    • 安装
    • 基本用法
    • 样例
      • 创建一个简单的命令行工具
      • 使用`archons`上下文创建进度条
    • 最后

项目地址: https://github.com/noctisynth/archons
Bug反馈或功能请求:https://github.com/noctisynth/archons/issues

项目简介

Archons意思是“执政官”,我使用Rust作为Nodejs的Native层并将方法通过napi-rs导出到Nodejs,这使得我们可以借助Rust来帮助Nodejs使用者创建高效、强大和优雅的终端命令行工具。

创建这个项目首先是由于citty项目的启发,但是citty很多更高级的功能并不完善,个人感觉社区活跃度也不高,因为我的PR至今没人处理。于是我便想着另起炉灶,但是既然都重写了,为什么不RIIR(Rewrite it in Rust)呢?Rust的命令行工具已经有了一套完整的生态,我们完全可以让Nodejs工具在Rust的肩膀上新生。

于是Archons应运而生。

从本质上来讲,我只是对Rust很多生态例如clapindicatif等库的套壳,但是这的确能够让我们的Nodejs命令行工具更加优雅和强大。我采用类似citty的函数式的声明方式,这能够更加清晰的进行开发。

安装

我们将archons作为开发依赖安装:

  1. 使用npm安装:

    npm install --save-dev archons
    
  2. 使用pnpm安装:

    pnpm add -D archons
    
  3. 使用yarn安装:

    yarn add -D archons
    
  4. 使用bun安装:

    bun add -d archons
    

基本用法

  1. defineCommand 方法

    构建一个基本的命令(或子命令)。

  2. run 方法

    将一个命令作为主命令并运行。

样例

所有样例:https://github.com/noctisynth/archons/tree/main/examples

命令行选项所有可用参数:https://github.com/noctisynth/archons/blob/main/index.d.ts#L66-L210

创建一个简单的命令行工具

Archons 中参数的行为将尽量与 clap 保持一致,部分参数由于Rust与Nodejs的差异,在代码文档中均有标注。

import { defineCommand, run, type Context } from 'archons';// 子命令
const dev = defineCommand({meta: {name: 'dev',about: 'Run development server',},options: {port: {type: 'option',parser: 'number',default: '3000',},},callback: (ctx: Context) => {console.log(ctx); // 这里输出完整的上下文console.log(ctx.args.port) // 这里port的值,缺省值为3000}
})const main = defineCommand({meta: {name: 'simple',version: '0.0.1',about: 'A simple command line tool',styled: true,  // 启用色彩},options: {name: {type: 'positional', // 位置参数required: true, // 必须传入help: 'Name of the person to greet',},verbose: {type: 'option',parser: 'boolean',action: 'store',help: 'Enable verbose output',global: true // 全局参数,会被子命令继承},},// 子命令subcommands: {dev,},callback: (ctx: Context) => {console.log(ctx);}
})run(main) // 执行主命令

使用archons上下文创建进度条

Archons 中进度条的创建行为与 indicatif 一致。

import { type Context, defineCommand, run } from 'archons'const spinner = defineCommand({meta: {name: 'spinner',},options: {'enable-steady-tick': {type: 'option',action: 'store',},},callback: async (ctx: Context) => {const spinner = ctx.createSpinner()spinner.setMessage('loading')spinner.tick()let i = 100const interval = ctx.args.interval as numberif (ctx.args['enable-steady-tick']) {spinner.println('Enabled steady tick')spinner.enableSteadyTick(interval)while (i--) {if (i < 30) {spinner.setMessage('Disabled steady tick for now')spinner.disableSteadyTick()}await new Promise((resolve) => setTimeout(resolve, interval))}} else {spinner.println('Disabled steady tick')while (i--) {spinner.tick()await new Promise((resolve) => setTimeout(resolve, interval))}}spinner.finishWithMessage('✨ finished')},
})const bar = defineCommand({meta: {name: 'bar',},options: {clear: {type: 'option',action: 'store',help: 'Clear the progress bar',parser: 'boolean',},},callback: async (ctx: Context) => {const bar = ctx.createProgressBar(ctx.args.total as number)bar.setTemplate('{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>5}/{len:5} {msg}')bar.setProgressChars('=>-')let i = 100const interval = ctx.args.interval as numberwhile (i--) {bar.inc(1)await new Promise((resolve) => setTimeout(resolve, interval))}if (ctx.args.clear) {bar.finishAndClear()} else {bar.finish()}console.log('✨ finished')},
})const main = defineCommand({meta: {name: 'progressbar',styled: true,subcommandRequired: true,},options: {interval: {type: 'option',numArgs: '1',default: '100',global: true,help: 'Interval of spinner',parser: 'number',},total: {type: 'option',numArgs: '1',default: '100',global: true,help: 'Total of progress bar',parser: 'number',},},subcommands: {spinner,bar,},
})run(main)

最后

如果你认为这个项目有所帮助,欢迎在GitHub给我一个Star哦!

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

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

相关文章

怎么投稿各大媒体网站?如何快速辨别一家媒体是否适合自己?

在做软文营销时&#xff0c;除去在官号和子账号上投稿外&#xff0c;怎么投稿各大媒体网站是困扰中小企业主的一大难题。没有多余账号、运营成本太高&#xff0c;让不少想做全平台推广的朋友止步于此。为了解决这些问题&#xff0c;今天就让小编来分享一下&#xff0c;怎么在各…

MES设备日志采集工具

永久免费: <下载> <使用说明> 用途 定时全量或增量采集工控机,电脑文件或日志. 优势 开箱即用: 解压直接运行.不需额外下载.管理设备: 后台统一管理客户端.无人值守: 客户端自启动,自更新.稳定安全: 架构简单,兼容性好,通过授权控制访问. 架构 技术架构: Asp…

Formality:参考设计/实现设计以及顶层设计

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482​​​ Formality存在两个重要的概念&#xff1a;参考设计/实现设计和顶层设计&#xff0c;本文就将对此进行详细阐述。参考设计/实现设计是中两个重要的全局概念&am…

国产编辑器EverEdit - 复制为RTF

1 复制为RTF 1.1 应用背景 在写产品手册或者其他文档时&#xff0c;可能会用到要将产品代码以样例的形式放到文档中&#xff0c;一般的文本编辑器拷贝粘贴到Word中也就是普通文本&#xff0c;没有语法着色&#xff0c;这样感观上不是太好&#xff0c;为了让读者的感观更好一点…

redux 结合 @reduxjs/toolkit 的使用

1&#xff0c;使用步骤 使用React Toolkit 创建 counterStore&#xff08;store目录下&#xff09; --> 为React注入store&#xff08;src下面的index&#xff09; --> React组件使用store中的数据&#xff08;组件&#xff09; 2&#xff0c;例如下面有一个简单加减的…

动态规划【打家劫舍】

今天和大家分享一下动态规划当中的打家劫舍题目&#xff0c;希望在大家刷题的时候提供一些思路 打家劫舍1&#xff1a; 题目链接&#xff1a; 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋…

【机器学习实战入门项目】使用Python创建自己的表情符号

深度学习项目入门——让你更接近数据科学的梦想 表情符号或头像是表示非语言暗示的方式。这些暗示已成为在线聊天、产品评论、品牌情感等的重要组成部分。这也促使数据科学领域越来越多的研究致力于表情驱动的故事讲述。 随着计算机视觉和深度学习的进步&#xff0c;现在可以…

BEVFusion论文阅读

1. 简介 融合激光雷达和相机的信息已经变成了3D目标检测的一个标准&#xff0c;当前的方法依赖于激光雷达传感器的点云作为查询&#xff0c;以利用图像空间的特征。然而&#xff0c;人们发现&#xff0c;这种基本假设使得当前的融合框架无法在发生 LiDAR 故障时做出任何预测&a…

OSI七层协议——分层网络协议

OSI七层协议&#xff0c;顾名思义&#xff0c;分为七层&#xff0c;实际上七层是不存在的&#xff0c;是人为的进行划分,让人更好的理解 七层协议包括&#xff0c;物理层(我),数据链路层(据),网络层(网),传输层(传输),会话层(会),表示层(表),应用层(用)(记忆口诀->我会用表…

【Mysql进阶知识】Mysql 程序的介绍、选项在命令行配置文件的使用、选项在配置文件中的语法

目录 一、程序介绍 二、mysqld--mysql服务器介绍 三、mysql - MySQL 命令行客户端 3.1 客户端介绍 3.2 mysql 客户端选项 指定选项的方式 mysql 客户端命令常用选项 在命令行中使用选项 选项(配置)文件 使用方法 选项文件位置及加载顺序 选项文件语法 使用举例&am…

wireshark抓路由器上的包 抓包路由器数据

文字目录 抓包流程概述设置抓包配置选项 设置信道设置无线数据包加密信息设置MAC地址过滤器 抓取联网过程 抓包流程概述 使用Omnipeek软件分析网络数据包的流程大概可以分为以下几个步骤&#xff1a; 扫描路由器信息&#xff0c;确定抓包信道&#xff1b;设置连接路由器的…

【蓝桥杯】43687.赢球票

题目描述 某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。 主持人拿出 N 张卡片&#xff08;上面写着 1⋯N 的数字&#xff09;&#xff0c;打乱顺序&#xff0c;排成一个圆圈。 你可以从任意一张卡片开始顺时针数数: 1,2,3 ⋯ ⋯ 如果数到的数字刚好和卡片上的数字…

微软开源AI Agent AutoGen 详解

AutoGen是微软发布的一个用于构建AI Agent系统的开源框架,旨在简化事件驱动、分布式、可扩展和弹性Agent应用程序的创建过程。 开源地址: GitHub - microsoft/autogen: A programming framework for agentic AI 🤖 PyPi: autogen-agentchat Discord: https://aka.ms/auto…

【Elasticsearch】全文搜索与相关性排序

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

用css和html制作太极图

目录 css相关参数介绍 边距 边框 伪元素选择器 太极图案例实现、 代码 效果 css相关参数介绍 边距 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}div{width: …

【React】插槽渲染机制

目录 通过 children 属性结合条件渲染通过 children 和 slot 属性实现具名插槽通过 props 实现具名插槽 在 React 中&#xff0c;并没有直接类似于 Vue 中的“插槽”机制&#xff08;slot&#xff09;。但是&#xff0c;React 可以通过 props和 children 来实现类似插槽的功能…

【Go】Go Gorm 详解

1. 概念 Gorm 官网&#xff1a;https://gorm.io/zh_CN/docs/ Gorm&#xff1a;The fantastic ORM library for Golang aims to be developer friendly&#xff0c;这是官网的介绍&#xff0c;简单来说 Gorm 就是一款高性能的 Golang ORM 库&#xff0c;便于开发人员提高效率 那…

【MySQL实战】mysql_exporter+Prometheus+Grafana

要在Prometheus和Grafana中监控MySQL数据库&#xff0c;如下图&#xff1a; 可以使用mysql_exporter。 以下是一些步骤来设置和配置这个监控环境&#xff1a; 1. 安装和配置Prometheus&#xff1a; - 下载和安装Prometheus。 - 在prometheus.yml中配置MySQL通过添加以下内…

【Apache Doris】周FAQ集锦:第 29 期

引言 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和开发者分享有关 Apache Doris 的常见问题。 通过这个每周 FAQ 栏目&#xff0c;希望帮助社…

Linux:文件描述符fd、系统调用open

目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说&#xff0c;如果在电脑上新建了一个空白文档&#xff0…