使用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 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
Mar 26 Javascript
使用jquery实现以post打开新窗口
Mar 19 Javascript
javascript 兼容各个浏览器的事件
Feb 04 Javascript
js如何打印object对象
Oct 16 Javascript
JavaScript使用DeviceOne开发实战(一) 配置和起步
Dec 01 Javascript
微信小程序 开发工具快捷键整理
Oct 31 Javascript
easy ui datagrid 从编辑框中获取值的方法
Feb 22 Javascript
Bootstrap缩略图的创建方法
Mar 22 Javascript
jQuery实现简单的计时器功能实例分析
Aug 29 jQuery
Angularjs实现数组随机排序的方法
Oct 02 Javascript
react-router 路由切换动画的实现示例
Dec 03 Javascript
详解mpvue中小程序自定义导航组件开发指南
Feb 11 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
wamp安装后自定义配置的方法
2014/08/23 PHP
CodeIgniter表单验证方法实例详解
2016/03/03 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
Thinkphp自定义生成缩略图尺寸的方法
2019/08/05 PHP
JavaScript表单常用验证集合
2008/01/16 Javascript
boxy基于jquery的弹出层对话框插件扩展应用 弹出层选择器
2010/11/21 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
js函数排序的实例代码
2013/07/01 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
Google Maps API地图应用示例分享
2014/10/23 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
第八篇Bootstrap下拉菜单实例代码
2016/06/21 Javascript
H5用户注册表单页 注册模态框!
2016/09/17 Javascript
HTML中setCapture、releaseCapture 使用方法浅析
2016/09/25 Javascript
微信小程序实现的涂鸦功能示例【附源码下载】
2018/01/12 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
2018/05/04 Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
2018/06/22 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
详解ES6 Symbol 的用途
2018/10/14 Javascript
jQuery使用bind动态绑定事件无效的处理方法
2018/12/11 jQuery
JavaScript类的继承操作实例总结
2018/12/20 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
基于vue实现一个禅道主页拖拽效果
2019/05/27 Javascript
JS数组扁平化、去重、排序操作实例详解
2020/02/24 Javascript
JS面向对象编程基础篇(三) 继承操作实例详解
2020/03/03 Javascript
[33:19]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第一场 11.26
2020/11/30 DOTA
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
Python脚本利用adb进行手机控制的方法
2019/07/08 Python
英文版餐饮业求职信
2013/10/18 职场文书
护理专业应届毕业生推荐信
2013/11/15 职场文书
出纳岗位职责范本
2013/12/01 职场文书
上班玩游戏检讨书
2014/02/07 职场文书
计划生育宣传标语
2014/06/21 职场文书
2014教师个人自我评价范文
2014/09/13 职场文书
生日寿星公答谢词
2015/09/29 职场文书
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python