1 前言
本文面向有 JavaScript 开发经验且希望入门 CLI 工具制作的开发人员。文中没有太多理论知识,通过从 0 到 1 开发一个简单的 CLI 工具,分享了 CLI 工具的开发、发布流程。看完本文,你可以学会如何"私人定制"一个 CLI 工具来提升开发效率。
总之,简单,实用,有趣。
2 什么是 CLI 工具
维基百科是这样定义 CLI 的
CLI(Command-line Interface),命令行界面,指通过输入字符组成的命令行进行操作的用户界面。
常见的 CLI 工具举例
系统命令:cd、mkdir、ifconfig
脚手架工具:create-react-app、vue-cli、yeoman
预处理器:less、sass、babel
测试工具:mocha、karma、wrk
构建工具:webpack、gulp、grunt
3 为什么要自己开发 CLI 工具
举例,如果想查看本机 ip 地址,通常我会使用 ifconfig 命令,如图:
ifconfig 执行结果
ip 执行结果
理想很丰满,现实很骨感。真实的情况是:当我在终端敲下 ip 命令时,系统给我的反馈是"command not found:ip"。
ip 执行结果
4 开始开发 CLI 工具
4.1 第一步:确保安装了 Node.js
node 版本检测 node 版本检测
4.2 第二步:编写脚本、测试运行
创建文件夹 ip-cli,并新建 index.js
编辑 index.js,内容如下
执行 node index.js,结果如下
执行脚本执行脚本
4.3 声明执行环境
执行 which env
which env
然后,代码就变成了下面这样:
代码中的 #!被称为 Shebang,是用来告诉编译器用什么命令执行文件的。Shebang 的一些具体用法罗列如下:
1、如果脚本文件中没有 #!这一行,那么执行时会默认采用当前 Shell 去解释这个脚本(即:
$ SHELL 环境变量)。
2、如果 #!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。
3、如果 #!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission
denied”。如果 #!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的 SHELL 去执行这个脚本。
4、如果 #!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到 $PATH 中寻找解释器的。
5、当然,如果你使用类似于”bash test.sh”这样的命令来执行脚本,那么 #!这一行将会被忽略掉,解释器当然是用命令行中显式指定的 bash。
6、脚本文件必须拥有可执行权限。
env 可以在系统的 PATH 目录中查找脚本解释器安装目录。
添加 #!/usr/bin/env node 是告诉系统,这个脚本使用 Node.js 来执行。这样我们就可以简化命令,执行 index.js 直接得到 ip 地址,不需要显式的调用 node index.js。
4.4 分配执行权限
在我们直接执行 index.js 后,结果如下:
执行 index.js
我们并没有得到 ip 地址,查看文件发现 index.js 没有可执行权限。
查看文件
执行 chmod +x index.js 给脚本分配可执行权限,然后 index.js 就可以执行了。
增加可执行权限
4.5 设置环境变量
执行 $PATH 查看环境变量
PATH
可以看到我电脑的 PATH 变量为
这里 usr 指 Unix System Resource,而不是 User, 通常/usr/bin 下面的都是系统预装的可执行程序,会随着系统升级而改变, /usr/local/bin 目录是给用户放置自己的可执行程序的地方,推荐放在这里,不会被系统升级而覆盖同名文件。如果两个目录下有相同的可执行程序,谁优先执行受到 PATH 环境变量的影响,比如我的电脑 PATH 变量中,/usr/local/bin 优先于/usr/bin。
接下来执行 ln index.js /usr/local/bin/ip,创建 index.js 的一个硬链接文件/usr/local/bin/ip,如图:
ln
ip
这时候可以选择使用 npm 管理项目,与他人共享开发成果。为了演示在 npm 项目中开发 CLI 工具的流程,我们暂时先删除刚才的命令 ip
删除命令
5 使用 npm 管理项目
5.1 初始化 npm 项目
执行 npm init -y 将项目初始化为 npm 项目。
初始化
目录结构如下:
5.2 设置 bin 字段
在 package.json 中设置 bin 字段,定义一个命令 ip 并指定该命令执行./index.js 文件。
5.3 测试 CLI 工具
执行 npm link ,在全局的 node_modules 下生成一个符号链接。
npm link
然后就可以在全局使用 package.json 中 bin 字段定义的命令 ip 了,执行 ip 命令结果如下
ip
5.4 发布 CLI 工具
执行 npm login 登录账号,登录成功后执行 npm whoami 可以看到 npm 用户名。
npm whoami
发布包的时候需要确保包的名字没有被占用,如下是包名冲突的情况。
npm publish
遇到这种情况可以选择换个名字或者加 scope,如下我给包名增加 scope,将包名由 ip-cli 改为 @qianxuemin/ip-cli。
加了 scope 后,发布包的时候需要设置访问级别,我们设置为公开。
npm publish
发布成功后,其他开发人员就可以通过 npm install @qianxuemin/ip-cli -g 安装并使用了。
ip
至此,一个简单的 CLI 工具开发、发布完成。
6 注意事项
上面演示了 CLI 工具的整体开发、发布流程,没有对细节做太多说明。如下总结了在日常开发 CLI 工具中需要注意的事项与大家分享:
2、工具应当包含 help 和 version 信息
3、工具应当包含运行指示,比如加载中
4、发布之前要到 https://www.npmjs.com 查找一下自己的包名有没有被占用,如果被占用需要先修改包名或加 scope
5、发布包时,可以通过在项目中添加.npmignore 或.gitignore 文件限制发布的文件内容,.npmignore 优先级高于.gitignore。或者在 package.json 中 files 字段设置发布哪些文件或目录,它的优先级高于 .npmignore 和 .gitignore。
7 开发 CLI 工具常用的库
相比原生 Node.js,使用一些开源模块能够简化 CLI 工具的开发,提高开发效率。如下是开发 CLI 工具常用的模块:
commander: 注册、解析命令行参数
Inquirer: 让命令行与用户进行交互
chalk: 给命令行字符加颜色
shelljs: 跨平台调用 shell 命令的 node 封装
Ora: 命令行提示图标
progress: 命令行进度条
blessed-contrib: 命令行可视化组件
download-git-repo:拉取 git 仓库源代码
由于文章篇幅有限,这里就不一一进行介绍了,使用时可以直接到 https://www.npmjs.com/搜索。
8 总结
本文通过一个简单的例子分享了 CLI 工具的开发、发布流程,并总结了一些开发注意事项和常用的库。旨在帮助 JavaScript 开发人员入门 CLI 工具开发。希望大家都能在掌握 CLI 工具开发流程后,发挥想象力,开发出一些实用、好玩的东西,让我们的开发变得高效、有趣。
作者介绍:
扣丁(企业代号名),目前负责贝壳新装修平台 B 端业务研发工作。
本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。
原文链接:
https://mp.weixin.qq.com/s/I8XXSw1eMbKLjFIcp9KWdQ
评论