使用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 相关文章推荐
JavaScript 实现模态对话框 源代码大全
May 02 Javascript
jQuery Ajax之$.get()方法和$.post()方法
Oct 12 Javascript
IE的有条件注释判定IE版本详解(附实例代码)
Jan 04 Javascript
jQuery 阴影插件代码分享
Jan 09 Javascript
JQuery事件e参数的方法preventDefault()取消默认行为
Sep 26 Javascript
javascript cookie基础应用之记录用户名的方法
Sep 20 Javascript
jquery 实时监听输入框值变化的完美方法(必看)
Jan 26 Javascript
Angularjs上传文件组件flowjs功能
Aug 07 Javascript
React通过父组件传递类名给子组件的实现方法
Nov 13 Javascript
vue使用代理解决请求跨域问题详解
Jul 24 Javascript
微信小程序中插入激励视频广告并获取收益(实例代码)
Dec 06 Javascript
js实现无缝轮播图特效
May 09 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
PHP关联链接常用代码
2012/11/05 PHP
php采用ajax数据提交post与post常见方法总结
2014/11/10 PHP
php显示时间常用方法小结
2015/06/05 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
利用php-cli和任务计划实现订单同步功能的方法
2017/05/03 PHP
php工具型代码之印章抠图
2018/07/18 PHP
使用Chrome浏览器调试AngularJS应用的方法
2015/06/18 Javascript
AngularJS 2.0新特性有哪些
2016/02/18 Javascript
javascript之Array 数组对象详解
2016/06/07 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
jquery实现点击页面回到顶部
2016/11/23 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
详细分析React 表单与事件
2020/07/08 Javascript
Vue项目利用axios请求接口下载excel
2020/11/17 Vue.js
详解Typescript里的This的使用方法
2021/01/08 Javascript
python执行get提交的方法
2015/04/29 Python
Python实现简单的代理服务器
2015/07/25 Python
Python 实现简单的电话本功能
2015/08/09 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
使用Django启动命令行及执行脚本的方法
2018/05/29 Python
selenium+python 对输入框的输入处理方法
2018/10/11 Python
python3.7实现云之讯、聚合短信平台的短信发送功能
2019/09/26 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
开发中都用到了那些设计模式?用在什么场合?
2014/08/21 面试题
仓库文员岗位职责
2014/04/06 职场文书
高中综合实践活动总结
2014/07/07 职场文书
民事诉讼授权委托书范文
2014/08/02 职场文书
土木工程专业本科生求职信
2014/10/01 职场文书
五好文明家庭事迹材料
2014/12/20 职场文书
常务副总经理岗位职责
2015/02/02 职场文书
2016抗战胜利71周年红领巾广播稿
2015/12/18 职场文书
浅谈Python实现opencv之图片色素的数值运算和逻辑运算
2021/06/23 Python
关于Spring配置文件加载方式变化引发的异常详解
2022/01/18 Java/Android