使用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 相关文章推荐
jQuery控制输入框只能输入数值的小例子
Mar 20 Javascript
jquery下div 的resize事件示例代码
Mar 09 Javascript
js 显示base64编码的二进制流网页图片
Apr 04 Javascript
javascript操作excel生成报表全攻略
May 04 Javascript
javascript实现tab切换的两个实例
Nov 05 Javascript
JS解决iframe之间通信和自适应高度的问题
Aug 24 Javascript
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
Dec 08 Javascript
ES6学习教程之对象字面量详解
Oct 09 Javascript
vue router demo详解
Oct 13 Javascript
Vue中使用sass实现换肤功能
Sep 07 Javascript
抖音上用记事本编写爱心小程序教程
Apr 17 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
Nov 05 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目录管理函数小结
2008/09/10 PHP
PHP的autoload自动加载机制使用说明
2010/12/28 PHP
php curl模拟post提交数据示例
2013/12/31 PHP
php json转换成数组形式代码分享
2014/11/10 PHP
详解js异步文件加载器
2016/01/24 PHP
CI框架中redis缓存相关操作文件示例代码
2016/05/17 PHP
CI框架数据库查询之join用法分析
2016/05/18 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
如何在一个页面显示多个百度地图
2013/04/07 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
Javascript全局变量var与不var的区别深入解析
2013/12/09 Javascript
javascript中apply和call方法的作用及区别说明
2014/02/14 Javascript
JS如何实现文本框随文本的长度而增长
2015/07/30 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
jQuery设置单选按钮radio选中/不可用的实例代码
2016/06/24 Javascript
针对后台列表table拖拽比较实用的jquery拖动排序
2016/10/10 Javascript
jquery表单验证插件validation使用方法详解
2017/01/20 Javascript
bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法
2017/02/10 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
基于JavaScript实现抽奖系统
2018/01/16 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
2018/09/13 Javascript
Node.js+ELK日志规范的实现
2019/05/23 Javascript
python3实现点餐系统
2019/01/24 Python
选择python进行数据分析的理由和优势
2019/06/25 Python
pyinstaller打包程序exe踩过的坑
2019/11/19 Python
python中PyQuery库用法分享
2021/01/15 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
2021/03/04 Python
CSS3属性 line-clamp控制文本行数的使用
2020/03/19 HTML / CSS
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
送给程序员的20个Java集合面试问题
2014/08/06 面试题
护理助产毕业生的求职信
2014/03/02 职场文书
绿色家庭事迹材料
2014/05/01 职场文书
介绍长城的导游词
2015/01/30 职场文书
spring boot中nativeQuery的用法
2021/07/26 Java/Android
oracle delete误删除表数据后如何恢复
2022/06/28 Oracle