構建優雅、高效的 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.pswp.cn/web/66266.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66266.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66266.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎么投稿各大媒體網站?如何快速辨別一家媒體是否適合自己?

在做軟文營銷時&#xff0c;除去在官號和子賬號上投稿外&#xff0c;怎么投稿各大媒體網站是困擾中小企業主的一大難題。沒有多余賬號、運營成本太高&#xff0c;讓不少想做全平臺推廣的朋友止步于此。為了解決這些問題&#xff0c;今天就讓小編來分享一下&#xff0c;怎么在各…

MES設備日志采集工具

永久免費: <下載> <使用說明> 用途 定時全量或增量采集工控機,電腦文件或日志. 優勢 開箱即用: 解壓直接運行.不需額外下載.管理設備: 后臺統一管理客戶端.無人值守: 客戶端自啟動,自更新.穩定安全: 架構簡單,兼容性好,通過授權控制訪問. 架構 技術架構: Asp…

rhel7.9利用有網絡環境打包ansible

RHEL7.9激活(可省略) # 注冊 subscription-manager register --usernameyour_username --passwordyour_password --auto-attach # 查看訂閱狀態 subscription-manager list # 將 “enabled1” 改為 “enabled0” vi /etc/yum/pluginconf.d/subscription-manager.conf 配置阿…

Formality:參考設計/實現設計以及頂層設計

相關閱讀 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482??? Formality存在兩個重要的概念&#xff1a;參考設計/實現設計和頂層設計&#xff0c;本文就將對此進行詳細闡述。參考設計/實現設計是中兩個重要的全局概念&am…

網絡安全中攻擊溯源有哪些方法?

目前網絡攻擊已經成為常見的安全威脅之一&#xff0c;其造成的危害和損失都是不可估量的&#xff0c;因此網絡攻擊受到了高度重視。而當我們遭遇網絡攻擊時&#xff0c;攻擊溯源是一項非常重要的工作&#xff0c;可以幫助我們迅速發現并應對各類網絡攻擊行為&#xff0c;那么網…

國產編輯器EverEdit - 復制為RTF

1 復制為RTF 1.1 應用背景 在寫產品手冊或者其他文檔時&#xff0c;可能會用到要將產品代碼以樣例的形式放到文檔中&#xff0c;一般的文本編輯器拷貝粘貼到Word中也就是普通文本&#xff0c;沒有語法著色&#xff0c;這樣感觀上不是太好&#xff0c;為了讓讀者的感觀更好一點…

【設計模式-結構型】裝飾器模式

一、什么是裝飾器模式 裝飾器模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它的核心思想是在不改變原有對象結構的情況下&#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;計劃偷竊沿街的房屋…

KVM創建ubuntu20.04虛機,部署K8S,再克隆出二份,做為Worker節點加入集群,通過Helm創建2個Pod,讓它們之間通過域名互訪

KVM創建ubuntu20.04虛機,部署K8S,再克隆出二份,做為Worker節點加入集群,通過Helm創建2個Pod,讓它們之間通過域名互訪 一.背景二.操作步驟1.安裝KVMA.在BIOS中開啟VT-dB.修改grub,開啟iommu在/etc/default/grub 中 GRUB_CMDLINE_LINUX行 添加 intel_iommuon iommupt重新創建引導…

【機器學習實戰入門項目】使用Python創建自己的表情符號

深度學習項目入門——讓你更接近數據科學的夢想 表情符號或頭像是表示非語言暗示的方式。這些暗示已成為在線聊天、產品評論、品牌情感等的重要組成部分。這也促使數據科學領域越來越多的研究致力于表情驅動的故事講述。 隨著計算機視覺和深度學習的進步&#xff0c;現在可以…

BEVFusion論文閱讀

1. 簡介 融合激光雷達和相機的信息已經變成了3D目標檢測的一個標準&#xff0c;當前的方法依賴于激光雷達傳感器的點云作為查詢&#xff0c;以利用圖像空間的特征。然而&#xff0c;人們發現&#xff0c;這種基本假設使得當前的融合框架無法在發生 LiDAR 故障時做出任何預測&a…

OSI七層協議——分層網絡協議

OSI七層協議&#xff0c;顧名思義&#xff0c;分為七層&#xff0c;實際上七層是不存在的&#xff0c;是人為的進行劃分,讓人更好的理解 七層協議包括&#xff0c;物理層(我),數據鏈路層(據),網絡層(網),傳輸層(傳輸),會話層(會),表示層(表),應用層(用)(記憶口訣->我會用表…

6. NLP自然語言處理(Natural Language Processing)

自然語言是指人類日常使用的語言&#xff0c;如中文、英語、法語等。 自然語言處理是人工智能&#xff08;AI&#xff09;領域中的一個重要分支&#xff0c;它結合了計算機科學、語言學和統計學的方法&#xff0c;通過算法對文本和語音進行分析&#xff0c;使計算機能夠理解、解…

Ubuntu使用指南

Ubuntu使用指南 一、Ubuntu虛擬機1、本地如何連接虛擬機&#xff0c;并設置虛擬機可以訪問外網 一、Ubuntu虛擬機 1、本地如何連接虛擬機&#xff0c;并設置虛擬機可以訪問外網 本地&#xff1a;WMware設置為橋接模式&#xff08;此時虛擬機可以看作一臺獨立主機&#xff09;…

【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 ? ? 如果數到的數字剛好和卡片上的數字…

SQL-leetcode—626. 換座位

626. 換座位 表: Seat -------------------- | Column Name | Type | -------------------- | id | int | | student | varchar | -------------------- id 是該表的主鍵&#xff08;唯一值&#xff09;列。 該表的每一行都表示學生的姓名和 ID。 ID 序列始終從 1 開始并連續…

微軟開源AI Agent AutoGen 詳解

AutoGen是微軟發布的一個用于構建AI Agent系統的開源框架,旨在簡化事件驅動、分布式、可擴展和彈性Agent應用程序的創建過程。 開源地址: GitHub - microsoft/autogen: A programming framework for agentic AI ?? PyPi: autogen-agentchat Discord: https://aka.ms/auto…