Node.js编写CLI的实例详解


Posted in Javascript onMay 17, 2017

Why Node.js?

常用的用来编写CLI的语言有 python, ruby, perl, Node.js等等。 为什么选取Node.js作为CLI的语言编写工具呢?有三个理由:

  1. 对Javascript语言更加熟悉
  2. npm 完善的生态系统
  3. npm OS无关的包管理机制

主要原因还是归咎于npm 完善的生态,目前npm官方有47.5万个三方包可供使用,你可以很方便的使用一些已经编写的很不错的轮子去帮你快速开发。另一方面,你不需要考虑跨平台的安装问题,比如OSX上的homebrew、Debian的aptitude、CentOS 上的yum。如果使用shell或者其它语言来编写CLI,需要针对各个主流OS来做兼容并且发布到不同的平台。

看个demo

Node.js编写CLI的实例详解

注: 此处的Logo使用的是figlet这个npm包来帮助生成

npm关联CLI的基本原理

如何让Node.js编写的包可执行?其实很简单,只需要在package.json里面增加一个bin字段。模块发布到npm上后,开发者安装这个包的时候会检查是否有bin字段,如果有bin字段则会使用软链接的方式创建可以全局使用的命令。

如果模块采用全局安装的方式,对于类unix系统,会在/usr/local/bin目录创建软链接,对于windows系统,在C:\Users\username\AppData\Roaming\npm目录创建软链接。

如果模块采用局部安装的方式,则会在项目内的./node_modules/.bin目录创建软链接。

配置好的package.json如下:

…
 "description": "A command line tool aims to improve front-end engineer workflow.",
 "main": "lib/index.js",
 "bin" : {
  "feflow" : "./bin/feflow"
 }
…

CLI基本命令设计

$ feflow --help

 A command line tool aims to improve front-end engineer workflow

 Usage: feflow [options] [command]

 Commands:
   init           Choose a scaffold to initialize project.
   scan   --receiver    Scan a group and mail to receiver
   install <plugin>     Install a plugin or a yeoman generator.

 Options:
   --version, -[vV]     Print version and exit successful
   --help,          Print this help and exit successf

Feflow的技术架构

Feflow总体分为3个模块,包括parser命令行参数解析、核心命令以及插件机制。设计插件主要是为了保持整体功能的稳定,避免频繁升级;同时开放能力,支持开发者接入,完善整体的生态。

Node.js编写CLI的实例详解

扫描器的实现

在一个工程项目中,有各种各样的规范,比如项目命名规范、描述规范、目录结构规范、README.md规范,是否增加基本监控等等。编写扫描器scanner,对某个Group里面的所有业务项目进行扫描,将不符合规范的仓库和不符合规范的地方列举出来,并且捞出责任人。最后通过邮件及定时任务发送给相关同学,并且敦促修改。扫描器流程图如下:

Node.js编写CLI的实例详解

首先,需要一个任务队列,队列里面存放不同的扫描任务。每个扫描任务依赖相关的文件信息或者Commit信息,这个时候需要调用Git code提供的三方API进行文件信息拉取。之后,需要编写一个规则引擎,这个规则引擎里面有多个规范相关的检查工具,解析完成后会将结果生成HTML格式的字符串。最后调用邮件服务和定时任务服务去通知相关开发者。

插件机制设计

$ feflow install <plugin>      # 安装一个插件, --force则会强制安装
$ feflow remove <plugin>      # 卸载一个插件
$ feflow list            # 列举出所有插件信息
$ feflow list <plugin>       # 列举某个插件信息

插件机制实现

插件机制的实现包括两个部分:插件注册机制和插件发现机制。feflow要求插件必须以feflow-plugin-开头或者 generator-开头,generator作为一种特殊的插件,插件代码以npm包的形式存储和管理。运行feflow install plugin命令时,会通过npm 的 regsitry检查是否存在插件,如果存在,会检查当前插件是否是最新版本。如果不是最新版本,则提示用户是否需要更新。然后将插件下载到Home目录下的.feflow目录(Windows系统为"C:\Users\username\.feflow" 目录)下的node_modules里面,并且写入到配置文件里面。

本地模块注册机制

Node.js编写CLI的实例详解

本地模块发现机制

Node.js编写CLI的实例详解

npm 的 registry服务

  1.  npm的查询服务网址:http://registry.npmjs.org/
  2. registry网址后面跟上模块名、版本好可以查询模块详细信息,包括最新版本,以此来判断模块是否需要更新。比如:React的最新版本可以通过http://registry.npmjs.org/react/latest 来获得
  3. 返回的JSON对象里面有个dist.tarball属性,是某个版本的压缩包地址

常用三方包分享

  1. osenv 方便的获取不同系统的环境和目录配置
  2. figlet 命令行炫酷的Logo生成器
  3. meow 命令行帮助命令封装
  4. inquire 强大的用户交互
  5. chalk 让命令行的output带有颜色
  6. easytable 表格信息展示,用于升级包的提示
  7. minimlist 用户输入的参数解析
  8. shelljs Node.js执行shell命令
  9. clui 进度条

遇到的问题

1,windows下用户未设置HOME环境变量导致报错

解决办法: 由于windows下HOME环境变量并非默认存在,因此不能直接使用。判断process.platform === ‘win32',优先使用HOME变量,否则使用USERPROFILE变量;建议使用osenv这个包。

2,OSX平台运行feflow报错: env: node\r: No such file or directory

解决办法: 由于类unix系统的换行符号为\n,而windows系统为\n\r。修复换行问题。可以在工程根目录下加.gitattributes文件,设置* text eol=lf,这样git提交时就不会讲LF转换成CRLF

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
ExtJS中设置下拉列表框不可编辑的方法
May 07 Javascript
jQuery下拉美化搜索表单效果代码分享
Aug 25 Javascript
jQuery Json数据格式排版高亮插件json-viewer.js使用方法详解
Jun 12 jQuery
JavaScript实现设置默认日期范围为最近40天的方法分析
Jul 12 Javascript
AjaxUpLoad.js实现文件上传功能
Mar 02 Javascript
vue中进入详情页记住滚动位置的方法(keep-alive)
Sep 21 Javascript
详解webpack loader和plugin编写
Oct 12 Javascript
详解js实时获取并显示当前时间的方法
May 10 Javascript
详解在vue-cli3.0中自定css、js和图片的打包路径
Aug 26 Javascript
vue跳转方式(打开新页面)及传参操作示例
Jan 26 Javascript
JS中间件设计模式的深入探讨与实例分析
Apr 11 Javascript
利用原生JS实现欢乐水果机小游戏
Apr 23 Javascript
ES6入门教程之Class和Module详解
May 17 #Javascript
AngularJS实现动态添加Option的方法
May 17 #Javascript
AngularJS+bootstrap实现动态选择商品功能示例
May 17 #Javascript
Vue声明式渲染详解
May 17 #Javascript
node.js调用Chrome浏览器打开链接地址的方法
May 17 #Javascript
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
May 17 #Javascript
AngularJS实现的回到顶部指令功能实例
May 17 #Javascript
You might like
基于curl数据采集之正则处理函数get_matches的使用
2013/04/28 PHP
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
JavaScript中的new的使用方法与注意事项
2007/05/16 Javascript
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
javascript类型转换使用方法
2014/02/08 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
基于jQuery 实现bootstrapValidator下的全局验证
2015/12/07 Javascript
js输出数据精确到小数点后n位代码
2016/07/02 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
浅析java线程中断的办法
2018/07/29 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
详解搭建es6+devServer简单开发环境
2018/09/25 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
在layui tab控件中载入外部html页面的方法
2019/09/04 Javascript
原生js实现二级联动菜单
2019/11/27 Javascript
js模拟实现烟花特效
2020/03/10 Javascript
[01:37]全新的一集《真视界》——TI7总决赛
2017/09/21 DOTA
[01:10:30]DOTA2-DPC中国联赛正赛 Dragon vs Dynasty BO3 第一场 3月4日
2021/03/11 DOTA
Python程序设计入门(4)模块和包
2014/06/16 Python
全面解读Python Web开发框架Django
2014/06/30 Python
python实现爬虫统计学校BBS男女比例之多线程爬虫(二)
2015/12/31 Python
python使用Tesseract库识别验证
2018/03/21 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
dpn网络的pytorch实现方式
2020/01/14 Python
python 工具 字符串转numpy浮点数组的实现
2020/03/14 Python
利用python对mysql表做全局模糊搜索并分页实例
2020/07/12 Python
Python爬虫回测股票的实例讲解
2021/01/22 Python
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
新闻专业大学生找工作的自我评价
2013/10/30 职场文书
哈弗商学院毕业生求职信
2014/02/26 职场文书
优秀的导游求职信范文
2014/04/06 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
项目投资意向书范本
2015/05/09 职场文书
2015年节能减排工作总结
2015/05/14 职场文书