原文:https://blog.fengjx.com/pages...
在软件开发中有很多重复性或者是繁琐的工作,通过一些命令行工具可以简化我们的日常工作,提高效率。
例如:
- 搭建项目初始开发环境: create-react-app, vue-cli
- http 客户端: httpie, curl
- git 终端 ui 客户端 gitui
随着 nodejs 的发展,已经在各领域都有完善的生态,使用 nodejs 开发命令行工具也是一个不错的选择
直接读源码可查看:https://github.com/fengjx/kit...
如何运行一个 nodejs 脚本
版本1
// hello.js
console.log('hello world')
执行
node hello.js
版本2
// hello.js
#!/usr/bin/env node
console.log('hello world')
执行
chmod 755 hello.js
./hello.js
工程化开发
运行一个 nodejs 脚本非常简单,可以和 shell 脚本一样。但是要实现一个完备的功能,我们通常需要依赖第三方类库。写好的工具提供给别人使用就需要一个发布平台。所以使用 npm 来管理项目是个很好的选择。
除此之外,一个易用的工具,应该给用户提供使用文档,告诉用户有哪些参数可以传,参数含义是什么。如果我们重新开发的话会是一件非常繁琐的事情,好在已经有第三方类库封装了这部分功能。下面是一些封装的比较好的类库。当然也远远不止这些。
更多第三方类库可查看:https://github.com/huaize2020...
以下是个简单 demo,更多用法参考官方文档
bin/hello.js
#!/usr/bin/env node
const { Command } = require('commander')
const inquirer = require('inquirer')
const program = new Command()
program.version('0.0.1')
console.log('hello node cli')
// https://github.com/tj/commander.js
// 解析命令行参数
// hello -d -n fengjx
program.option('-d, --debug', 'debug')
program.option('-n, --name ', 'your name')
program.parse(process.argv)
const opts = program.opts()
if (opts.debug) {
console.log('opts: ', opts)
}
console.log(`hello: ${opts.name}`)
// https://github.com/SBoudrias/Inquirer.js/tree/master/packages/inquirer/examples
// 交互式终端
const questions = [
{
type: 'input',
name: 'username',
message: "输入账号",
},
{
type: 'password',
name: 'password',
message: "输入密码"
}
]
inquirer.prompt(questions).then((answers) => {
console.log(JSON.stringify(answers, null, ' '))
})
执行
$ node bin/hello.js -d -n fengjx
hello node cli
opts: { debug: true, name: 'fengjx' }
hello: fengjx
? 输入账号 fjx
? 输入密码 [hidden]
{
"username": "fjx",
"password": "1024"
}
基础框架设计
对于一个命令行工具来说,通常包含以下步骤:
- 定义参数
- 参数校验&解析
- 读取参数,并执行相关逻辑
我们可以封装一个统一的接口,不同的工具实现对应方法,相同的逻辑全都放到入口函数即可,每个命令只需要实现对应接口的方法。
接口Cmd
定义
cmd.js
/**
* 命令接口
*/
class Cmd {
/**
* 命令名称
*
* @returns string
*/
actionName() {
}
/**
* 命令参数配置
* @returns Option[]
*/
makeOptions() {
}
/**
* 业务逻辑
* @param {*} opts 参数解析结果
*/
// eslint-disable-next-line no-unused-vars
exec(opts) {
}
}
module.exports = Cmd
完整项目代码: https://github.com/fengjx/kit
打包&安装
功能开发好之后,我们需要发布给别人使用,如果是有 node 环境可以直接使用源码安装,也可以直接打包成一个可执行文件,这样别人使用的时候不需要再安装 node。
通过 npm 全局安装
git clone https://github.com/fengjx/kit.git
cd kit
# 安装依赖
npm i
# 全局安装
npm i -g .
# 测试是否安装成功
kit --help
打包可执行文件
nodejs 的执行需要依赖 v8 引擎,所以需要 node 环境才能运行,pkg
这个工具可以将 node 环境和代码打包到一起(所以打出来的包会比较大 50M 左右),得到一个可执行文件,可以把文件上传到 cdn 提供别人直接下载使用。
在package.js
中定义了打包命令
"pkg:mac": "pkg . --targets node14-macos-x64 --output ./.dist/kit-macos-64",
"pkg:win": "pkg . --targets node14-win-x64 --output ./.dist/kit-win-64",
"pkg:linux": "pkg . --targets node14-linux-x64 --output ./.dist/kit-linux-64",
不同平台需要指定不同的参数,更多参数可以参考官方文档:https://github.com/vercel/pkg
通过 npm 打包不同平台下的包
npm run pkg:mac # pkg:win or pkg:linux
测试
$ cd .dist
$ ./kit-macos-64 hello --version
1.0.0
$ ./kit-macos-64 --help
Usage: kit [options] [command]
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
hello [options]
gl-bcl [options]
help [command] display help for command