——————————☆☆☆——————————

Node 系列相应地址:

  • 代码仓库:https://github.com/LiangJunrong/all-for-one

  • 文章仓库:https://github.com/LiangJunrong/document-library/tree/master/系列-前端资料/Node

——————————☆☆☆——————————

commander.js —— 完整的 Node.js 命令行解决方案。

本篇文章讲解如何通过 commander.js 溜达 Node.js 命令行。

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 前言
三 commander.js
四 实践:文件重排功能
 4.1 实践目录
 4.2 编写 commander
 4.3 编写排序功能
 4.4 运行内容
五 常用 commander 配置
六 参考文献

二 前言

当一个 Node.js 程序运行时,会有许多存在内存中的全局变量。

其中 process 作为进程对象,它有一个 argv 属性,可以查看到指令。

我们随便建一个 index.js 举例,终端执行命令:node index.js --name jsliang

index.js

console.log(process.argv);
/*['C:\\Program Files\\nodejs\\node.exe','F:\\jsliang\\index.js','--name','jsliang']
*/

看打印的数据:

  • Node 位置:C:\\Program Files\\nodejs\\node.exe

  • 当前代码路径:F:\\jsliang\\index.js

  • 参数 1:--name

  • 参数 2:jsliang

所以,在我们写命令行程序的时候,只需要对 process.argv 这个数组的第三个元素及其之后的参数进行解析即可。

如果不嫌麻烦,完全可以写出很多判断分支来做。

但是,有现成的为啥还要自己写,能偷懒就偷懒啊~

三 commander.js

commander.jstj 写的一个工具包,作用是让 Node 命令行程序的制作更加简单:

  • GitHub:commander

懂你,中文 README 奉上:https://github.com/tj/commander.js/blob/master/Readme_zh-CN.md

下面我们开始操作:

  • 初始化 package.jsonnpm init --yes

    • !!【注】如果是按照 Node 系列顺序学习的,这个步骤可以省略

    • !!【注】下面代码可以建一个 test 空文件夹来耍耍

  • 安装包:npm i commander

  • 编写指令文件:

index.js

const program = require('commander');program.version('0.0.1').description('小工具指令清单').option('-s, --sort <path>', '排序功能', '')program.parse(process.argv);

package.json(自动生成)

{"name": "test","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"commander": "^7.2.0"}
}

这份代码的逻辑是:

  1. 引用 commander

  2. 描述 commanderversion 等参数

  3. commander 掌控 process.argv

重点看看在这份代码中第 2 段的参数:

参数什么的看起来很烦躁,但是不了解又不知道还可以怎么用

  • version:版本

    • 用法:.version('x.y.z')

  • description:描述

    • 用法:.description('小工具指令清单')

  • option:选项

    • 用法:.option('-n, --name <name>', 'your name', 'jsliang')

    • 第一个参数是选项定义,可以用 |,' ' 空格连接

    • 第二个参数为选项描述

    • 第三个参数为选项参数默认值(可选)

所以下面我们可以查看到一些信息。

  • 执行命令:node index.js -h

得到下面结果:

Usage: index [options]小工具指令清单Options:-V, --version           output the version number-s, --sort <path>       排序功能 (default: "")-h, --help              display help for command

这样我们就完成了一些小指令,那么怎么操作呢?

  • 排序:node index.js -s "jsliang"

当然,这样感觉太怪了,能不能像日常开发一样,可以 npm run devnpm run xxx 的方式执行?

当然是可以的!

四 实践:文件重排功能

讲了那么多,做个小实践吧!


对于 Markdown 编写的文档库来说,如果你不设置文档顺序,那么它就会按照系统的规则来读取目录:

  • 1.文章 1

  • 10.文章 10

  • 2.文章 2

  • ……

当一个文件夹内容过多的时候,我们希望按照自己的顺序让用户阅读,所以不能找系统的来,因此需要用 Node 写个小工具,读取的时候按照希望的排序来读取,这就是我们开发小工具的初衷。

当然,还有个很重要的功能,就是当我们希望在第 1 篇和第 2 篇文章中间插入一篇文章的时候,例如:

  • 1.文章 1

  • 1-1.文章 1-1

  • 2.文章 2

  • ……

我们还需要将这个目录结构进行重新排序,让新文章插入到指定位置。

4.1 实践目录

此时我们的目录为:

+ docs+ 3.目录c- 1.目录c1.md- 1-1.目录c2.md- 2.目录c3.md- 1.文章a.md- 2.文章b.md- 10.文章d.md
+ src- config.ts- index.ts【已有】- sortCatalog.ts
- .eslintrc.js【已有】
- package.json【已有】
- tsconfig.json【已有】

该目录的 .eslintrc.jspackage-lock.jsonpackage.jsontsconfig.json 是自动创建的,TypeScript 的配置看前置文章,这里不做累述。

docs 目录下创建几个空 Markdown 文件,文件名照抄即可。

为了避免小伙伴误操作,还是截个图吧

4.2 编写 commander

加入 commonder 只需要往 package.jsonindex.ts 上配置即可。

  • 初始化 package.jsonnpm init --yes(之前已配置)

  • 安装 commandernpm i commander

package.json

{"name": "jsliang","version": "1.0.0","description": "FE-util","main": "index.js","scripts": {"sort": "ts-node ./src/index.ts sort"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@types/node": "^15.0.2","@typescript-eslint/eslint-plugin": "^4.23.0","@typescript-eslint/parser": "^4.23.0","eslint": "^7.26.0","ts-node": "^9.1.1","typescript": "^4.2.4"},"dependencies": {"commander": "^7.2.0"}
}

注意 scripts 改变了,记得复制过去

然后简单写写 index.ts 里面内容

src/index.ts

import program from 'commander';
import { sortCatalog } from './sortCatalog';program.version('0.0.1').description('工具库')program.command('sort <path>').description('文件排序功能。示例:npm run sort "docs" 或者 npm run sort " C:/code/jsliang/src/docs"').action((path: string) => {sortCatalog(`../${path}`); // 为了更便捷,先退一层到外边});program.parse(process.argv);

4.3 编写排序功能

准备好基础配置之后,只需要往 sortCatalog.ts 里面添加内容即可:

src/sortCatalog.ts

/*** @name 文件排序功能* @time 2021-05-22 16:08:06* @description 规则1. 系统顺序 1/10/2/21/3,希望排序 1/2/3/10/212. 插入文件 1/2/1-1,希望排序 1/2/3(将 1-1 变成 2,2 变成 3)
*/
import fs from 'fs';
import path from 'path';
import { IGNORE_PATH } from './config';const recursion = (filePath: string, level = 0) => {const files = fs.readdirSync(filePath);files.filter((item => !IGNORE_PATH.includes(item))) // 过滤忽略文件/文件夹.sort((a, b) =>Number((a.split('.')[0]).replace('-', '.'))- Number((b.split('.')[0]).replace('-', '.'))) // 排序文件夹.forEach((item, index) => { // 遍历文件夹// 设置旧文件名称和新文件名称const oldFileName = item;const newFileName = `${index + 1}.${oldFileName.slice(oldFileName.indexOf('.') + 1)}`;// 设置旧文件路径和新文件路径const oldPath = `${filePath}/${oldFileName}`;const newPath = `${filePath}/${newFileName}`;// 判断文件格式const stat = fs.statSync(oldPath);// 判断是文件夹还是文件if (stat.isFile()) {fs.renameSync(oldPath, newPath); // 重命名文件} else if (stat.isDirectory()) {fs.renameSync(oldPath, newPath); // 重命名文件夹recursion(newPath, level + 1); // 递归文件夹}});
};export const sortCatalog = (filePath: string): boolean => {// 绝对路径if (path.isAbsolute(filePath)) {recursion(filePath);} else { // 相对路径recursion(path.join(__dirname, filePath));}return true;
};

有小伙伴看完肯定好奇 config.ts 是什么,其实就是全局配置而已:

/*** @name 默认的全局配置* @time 2021-05-22 16:12:21*/
import path from 'path';// 基础目录
export const BASE_PATH = path.join(__dirname, './docs');// 忽略目录
export const IGNORE_PATH = ['.vscode','node_modules',
];

当我们没有配置的时候,就给默认的配置。

4.4 运行内容

OK,准备完毕,就可以耍起来了。

当前 docs 下目录结构为:

- 1.文章a.md
- 10.文章d.md
- 2.文章b.md
- 3.目录c- 1-1.目录c2.md- 1.目录c1.md- 2.目录c3.md

而我们运行 npm run sort "docs" 后,新目录列表变成了:

- 1.文章a.md
- 2.文章b.md
- 3.目录c- 1.目录c1.md- 2.目录c2.md- 3.目录c3.md
- 4.文章d.md

这样,我们简单的案例就做好啦!是不是非常简单!

五 常用 commander 配置

下面例举下我们非常不想看,但是正常使用又常见的 commander 配置:

  • version:版本。用来设置命令程序的版本号

    • 用法:.version('x.y.z')

  • description:描述。用来设置命令的描述

    • 用法:.description('小工具指令清单')

  • option:选项。

    • 用法:.option('-n, --name <name>', 'your name', 'jsliang')

    • 第一个参数是选项定义,可以用 |,' ' 空格连接,参数可以用 <>(必填)或者 [](选填)修饰

    • 第二个参数为选项描述

    • 第三个参数为选项参数默认值(可选)

  • command:命令

    • 当没有第二个参数时,commander.js 将返回 Command 对象

    • 当带有第二个参数,将返回原型对象,并且没有显示调用 action(fn) 时,将会使用子命令模式

    • 子命令模式:./pm./pm-install./pm-search 等,这些子命令跟主命令在不同的文件中

    • 用法:.command('init <path>', 'description')

    • command 用法稍微复杂,原则上接受 3 个参数,第一个为命令定义,第二个命令描述,第三个为命令辅助修饰对象

    • 第一个参数可以使用 <> 或者 [] 修饰命令参数

    • 第二个参数可选

    • 第三个参数一般不同,他可以设置是否显示使用的子命令模式

  • action:动作。用来设置命令执行的相关回调

    • 用法:.action(fn)

    • fn 可以接受命令的参数为函数形参,顺序与 command() 中定义的顺序一致

  • parse:解析 process.argv

    • 用法:program.parse(process.argv)

    • 这个 API 一般在最后调用,用来解析 process.argv

OK,commander 的简单介绍到此结束,我们下期见!

六 参考文献

  • Github:commander

  • W3CSchool:使用commander.js做一个Nodejs命令行程序


jsliang 的文档库由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。
基于 https://github.com/LiangJunrong/document-library 上的作品创作。
本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。

Node 系列 - 003 - commander.js相关推荐

  1. Node.js之commander.js学习笔记

    概述 commander.js可以用来写命令行工具. 官网地址:Commander.js 安装与引入 安装 执行如下命令进行安装,但前提是有node环境,即能使用npm命令进行安装: npm inst ...

  2. Node 系列 - 007 - node-xlsx

    ----------☆☆☆---------- Node 系列相应地址: 代码仓库:https://github.com/LiangJunrong/all-for-one 文章仓库:https://g ...

  3. commander.js

    参考链接: http://yijiebuyi.com/blog/2cd3833e8551a302b4ec645031bfd3d0.html http://blog.gejiawen.com/2016/ ...

  4. 四、node系列之购物车的业务逻辑

    node系列之购物车的业务逻辑 1.加入购物车业务逻辑 1.1 创建购物车模块 myapp/routes/cart.js 1.2 app.js中注册路由 1.3 设计购物车的数据库集合 1.4 加入购 ...

  5. commander.js使用及源码分析

    commander.js commander是一个轻巧的nodejs模块,提供了用户命令行输入和参数解析强大功能. commander的特性: 自记录代码 自动生成帮助 合并短参数 默认选项 强制选项 ...

  6. commander.js基本用法

    准备工作 安装nodejs 安装commander.js,执行npm install commander --save version方法 作用:定义命令程序的版本号 参数说明: 版本号<必须& ...

  7. commander.js学习总结

    commander是用于快捷开发命令行工具,提高开发效率的工具包. 官网: https://github.com/tj/commander.js/blob/master/Readme_zh-CN.md ...

  8. commander.js教程笔记

    并非严格的教程博文,属于是个人在学习过程中的笔记心得汇总. 内容相对官方文档更通俗一些,入门新人,如果看不懂官方文档,可以大致看一看这个.有错的话请指正,标准的还得看官方文档. 1.commander ...

  9. 玩转 Commander.js —— 你也是命令行大师

    导语 | 最近做团队底层构建工具架构升级和命令行交互打了不少交道,再加上在研究 Vue-CLI 的源码,觉得 Commander.js 作为 Node.js 下这么优秀的命令行交互工具,值得总结一下, ...

最新文章

  1. Docker使用遇到问题Got permission denied while trying to connect to the Docker daemon socket解决方案
  2. C#的变迁史 - C# 2.0篇
  3. 图解用工具对PE文件格式做初步研究
  4. VirtualBox 虚拟机转换为KVM虚拟机
  5. LuoguP4606 [SDOI2018]战略游戏
  6. 浅谈auto_ptr智能指针
  7. WordPress 获取当前页面 ID 的几大方法
  8. java+set+split_阿里资深工程师教你如何优化 Java 代码!
  9. Ubunt 配置网络服务
  10. easyui学习笔记一:主要结构
  11. hadoop入门学习教程--DKHadoop完整安装步骤
  12. Uva 1471 Defense Lines(LIS变形)
  13. 虚幻4——实时渲染学习笔记
  14. hi3519叠加OSD
  15. A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHM
  16. 男孩子读博好处--转载
  17. 【最新技术早知道】PCIe Gen5 还没用上,Gen6 就来了?PCIe 6.0 系列文章之:《PCIe 6.0,到底 6 在哪?》
  18. 【bzoj1150】【CSTC2007】【数据备份】【贪心】
  19. C++函数UpdateData()有什么作用?
  20. INET_ATON() 和 INET_NTOA()

热门文章

  1. GitHub 热点速览 Vol.30:那些提升效率的小工具们
  2. Linux下使用 github+hexo 搭建个人博客04-next主题优化
  3. farpoint 小数保留4位_Farpoint表格编辑的功能用法总结
  4. 数据库事务与TransactionScope代码事务区别
  5. 【HAL库】STM32CubeMX开发----STM32F407----CAN通信实验
  6. 心情不好的时候就想化妆……
  7. 当我不再依赖你的时候说说_「精选」关于依赖一个人的说说()-说说控
  8. abstract类和abstract方法
  9. 使用Mac技巧:如何解决Mac大写锁定键失灵?
  10. wind7 管理员权限设置方法