使用typescript快速开发一个cli的实现示例


Posted in Javascript onDecember 09, 2020

cli 的全称 command-line interface(命令行界面),也就是前端同学常用的脚手架,比如 yo、vue cli、react cli 等。

cli 可以方便我们快速创建项目,下图是引用 vue cli 的介绍:

使用typescript快速开发一个cli的实现示例

创建项目

运行下面的命令,创建一个项目:

npm init

执行命令完成后,可以看到项目根目录只有一个 package.json 文件。

使用typescript快速开发一个cli的实现示例

在 package.json 文件增加 bin 对象,并指定入口文件 dist/index.js。

在命令行运行需要在入口文件的第一行增加 #!/usr/bin/env node,告诉系统用 node 运行这个文件。

{
 "name": "cli-demo",
 "version": "0.0.1",
 "description": "cli demo",
 "keywords": [
 "cli"
 ],
 "bin": {
 "cli-demo": "dist/index.js"
 }
 ...
}

安装依赖

命令行工具,也会涉及到用户交互的动作,那么 node.js 是怎么实现呢?早有大佬提供了非常好的库,我们只要拿过来用,主要有两个库:

  • commander:完整的 node.js 命令行解决方案。
  • inquirer:交互式命令行工具。

将这两个库安装到项目里:

yarn add commander inquirer

由于是用 typescript 开发,再通过 rollup 打包,先安装相关的依赖库:

yarn add typescript rollup rollup-plugin-terser rollup-plugin-typescript2 @types/inquirer -D

配置

由于是用 typescript 开发,首先需要配置一下 tsconfig.json。

{
 "compilerOptions": {
 "target": "ES6",
 "module": "ESNext",
 "sourceMap": false,
 "declaration": false,
 "outDir": "./dist",
 "moduleResolution": "Node",
 "esModuleInterop": true,
 "resolveJsonModule": true,
 "removeComments": false,
 "importHelpers": true,
 "strict": true,
 "lib": ["ES6", "DOM"]
 },
 "include": ["src"]
}

接下来在根目录增加一个 rollup.config.js,把 typescript 代码编译成 javascript 代码。前面提到的要在第一行增加 #!/usr/bin/env node 来告诉系统用 node 运行,那么可以在 rollup.config.js 的 banner 选项,把 #!/usr/bin/env node 写在最前面。

import typescript from 'typescript'
import json from '@rollup/plugin-json'
import { terser } from 'rollup-plugin-terser'
import typescript2 from 'rollup-plugin-typescript2'

import { dependencies } from './package.json'

const external = Object.keys(dependencies || '')
const globals = external.reduce((prev, current) => {
 const newPrev = prev

 newPrev[current] = current
 return newPrev
}, {})

const defaultConfig = {
 input: './src/index.ts',
 output: {
 file: './dist/index.js',
 format: 'cjs',
 banner: '#!/usr/bin/env node',
 globals
 },
 external,
 plugins: [
 typescript2({
  exclude: 'node_modules/**',
  useTsconfigDeclarationDir: true,
  typescript,
  tsconfig: './tsconfig.json'
 }),
 json(),
 terser()
 ]
}

export default defaultConfig

实现一个简单的 cli

在根目录创建一个 src 文件夹,然后再创建一个 index.ts

添加引用

添加引用并实例化 Command 对象。

import { Command } from 'commander'
import pkg from '../package.json'

const program = new Command(pkg.name)

自定义命令

实现一个可交互的自定义命令,模拟在终端(命令行)的登录功能。使用 command 方法创建一个命令,description 可以用来描述这个命令的作用,登录处理逻辑则写在 action 方法里。最后使用 parse(process.argv) 方法,解析命令。更多详细介绍和使用,可移步:https://github.com/tj/commander.js/blob/master/Readme_zh-CN.md。

program
 .command('login')
 .description('模拟登录。')
 .action(() => {
  handleLogin()
 })

program.parse(process.argv)

交互的话,用到前面说的 inquirer 库,接收输入的用户名和密码。选项的 type 的值有 inputpasswordnumbercheckboxeditorlistrawListexpandconfirm,选项 nameinquirer.prompt 方法返回的对象,选项 validate 可用来验证输入是否符合规则。更多详细介绍和使用,可移步:https://github.com/SBoudrias/Inquirer.js/blob/master/README.md

如果选项 typepassword,可通过 mask 设置掩码。

const handleLogin = () => {
 // 配置交互的用户名和密码
 const prompt = [
 {
  type: 'input',
  name: 'userName',
  message: '用户名:',
  validate: (value: string) => value.length > 0 || '用户名不能为空'
 },
 {
  type: 'password',
  name: 'password',
  message: '密码:',
  mask: '? ',
  validate: (value: string) => value.length > 0 || '密码不能为空'
 }
 ]

 inquirer.prompt(prompt).then(({ userName, password }) => {
 if (userName === 'demo' || password === '123456') {
  console.log('登录成功')
  return
 }
 console.log('用户名或密码错误')
 })
}

其他

一个 cli 工具,帮助信息也是必须的,可以通过 on('--help') 修改自定义帮助信息。

必须在 parse 方法之前。

program.on('--help', () => {
 console.log('\n运行 cli-demo -h | --help 查看命令使用。\n')
})

然后再来修改一下,没有输入任何参数的时候,会出现错误,可以使用 exitOverride 方法重新退出,在终端(命令行)输出帮助信息。

program.exitOverride()

try {
 program.parse(process.argv)
} catch (error) {
 program.outputHelp()
}

到这里,一个简单的 cli 工具完成了,先本地来测试下看看。在终端(命令行)输入 npm link,生成一个全局软连接,可以方便调试和测试。

使用typescript快速开发一个cli的实现示例

到此这篇关于使用typescript快速开发一个cli的实现示例的文章就介绍到这了,更多相关typescript开发cli内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js转化毫秒为时间格式代码
Apr 10 Javascript
JS获得浏览器版本和操作系统版本的例子
May 13 Javascript
移除AngularJS下URL中的#字符的方法
Jun 19 Javascript
jQuery实现商品活动倒计时
Oct 16 Javascript
原生JS实现《别踩白块》游戏(兼容IE)
Feb 20 Javascript
video.js使用改变ui过程
Mar 05 Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
Apr 11 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
Jul 21 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
Dec 26 Javascript
vue使用pdfjs显示PDF可复制的实现方法
Dec 14 Javascript
vue props default Array或是Object的正确写法说明
Jul 30 Javascript
AJAX实现指定部分页面刷新效果
Oct 16 Javascript
ES6中的类(Class)示例详解
Dec 09 #Javascript
JavaScript实现表单验证功能
Dec 09 #Javascript
element中Steps步骤条和Tabs标签页关联的解决
Dec 08 #Javascript
javascript全局自定义鼠标右键菜单
Dec 08 #Javascript
javascript局部自定义鼠标右键菜单
Dec 08 #Javascript
JavaScript对象访问器Getter及Setter原理解析
Dec 08 #Javascript
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 #Vue.js
You might like
分享8个最佳的代码片段在线测试网站
2013/06/29 PHP
php一次性删除前台checkbox多选内容的方法
2013/09/22 PHP
PHP实现的简单日历类
2014/11/29 PHP
PHP和C#可共用的可逆加密算法详解
2015/10/26 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
PHP递归的三种常用方式
2019/02/28 PHP
PHP保存Base64图片base64_decode的问题整理
2019/11/04 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
js 巧妙去除数组中的重复项
2010/01/25 Javascript
理解Javascript_13_执行模型详解
2010/10/20 Javascript
javascript学习笔记(九) js对象 设计模式
2012/06/19 Javascript
js 判断一个元素是否在页面中存在
2012/12/27 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
2013/11/25 Javascript
js Array操作的最简短最容易理解方法
2013/12/09 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
jQuery与JS加载事件用法分析
2016/09/04 Javascript
easyUI实现类似搜索框关键词自动提示功能示例代码
2016/12/27 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
JavaScript设计模式之享元模式实例详解
2019/01/17 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
2019/03/09 Javascript
使用vue-router切换页面时实现设置过渡动画
2019/10/31 Javascript
搞笑的程序猿:看看你是哪种Python程序员
2015/06/12 Python
Django框架中的对象列表视图使用示例
2015/07/21 Python
在CentOS6上安装Python2.7的解决方法
2018/01/09 Python
详解Python3 基本数据类型
2019/04/19 Python
python实现共轭梯度法
2019/07/03 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析
2020/03/08 Python
Python无头爬虫下载文件的实现
2020/04/02 Python
Python3.9.1中使用split()的处理方法(推荐)
2021/02/07 Python
美国乒乓球设备、配件和服装品牌:Killerspin
2020/06/07 全球购物
化工专业求职信
2014/07/01 职场文书
交通运输局四风问题对照检查材料思想汇报
2014/10/09 职场文书
2014年物流工作总结
2014/11/25 职场文书
爱心募捐通知范文
2015/04/27 职场文书
SQLServer2019 数据库环境搭建与使用的实现
2021/04/08 SQL Server