持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
前言
大家好,我是小阵 🔥,一路奔波不停的码字业务员
身为一个前端小菜鸟,总是有一个飞高飞远的梦想,因此,每点小成长,我都想要让它变得更有意义,为了自己,也为了更多值得的人
如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~😋
加我微信:zzz886885,邀你进群,一起学习交流,摸鱼学习两不误🌟
开开心心学技术大法~~
来了来了,他真的来了~
正文
看起来有点高大上,其实就是通过cli自己做了个git命令的二次封装而已。
当然,这个功能也可以通过git alias来实现
看到这里小伙伴其实已经可以猜到下面要做的事情了,简单来说就是
将testcli acm xxxx通过node转成git add . && git commit -m xxx而已,当然这只是一个示例,更多功能还有待拓展。
重要的是实现过程和思路,之前掘金也有很多类似的教程,我借花献佛而已,希望大家不要介意!
直接掘金搜索
cli即可
初始化cli
mkdir testcli && cd testcli
npm init -y
新建一个testcli目录,并且进入到testcli目录执行npm init -y来创建一个初始化的npm仓库
然后通过package.json的bin字段创建一个cli入口
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"bin": {
"testcli": "bin/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"chalk": "^5.0.1",
"child_process": "^1.0.2",
"commander": "^9.3.0",
"inquirer": "^8.2.4"
}
}
关键是上面的bin字段,指向了bin/index.js。
主要的cli功能都是在这个bin/index.js中实现的。
#! /usr/bin/env node
// 文件的第一行一定要是这样,告诉终端要基于电脑的env环境,通过node来执行该文件
...
link全局命令
可以看到上面我们定义了bin的key是testcli,value就是bin/index.js,那么按照我们的预期,是希望在终端输入testcli来执行我们定义的bin/index.js文件。
实际上我们在运行时会发现终端提示了command not found: testcli。
为什么会这样呢?原来是我们平时所输入的类似于npm,cnpm命令等都是在全局环境变量中注册过的,所以我们可以直接在终端中通过输入已经注册好的变量来唤起指定的cmd入口,这个里的cmd入口其实就是类似我们上面自己定义的bin/index.js文件。
那我们要怎样注册这个全局变量呢?
1.通过npm -g testzzz 来注册
当然目前来看,这是不可能的,因为我们的testzzz还在本地,并没有发布到npm上。
2.通过npm link testcli 来做临时的全局环境绑定
等项目上线之后再通过npm -g testzzz来安装即可。
git命令包装
#! /usr/bin/env node
import { Command } from 'commander'
import child_process from 'child_process'
import util from 'util'
import chalk from 'chalk'
import { readFile } from 'fs/promises'
const packageJson = JSON.parse(
await readFile(new URL('../package.json', import.meta.url))
)
const program = new Command()
const exec = util.promisify(child_process.exec)
program
.command('acm')
.description('执行回退到上一个版本')
.option("-m --message", "commit message")
.action((name) => {
console.log('name', name)
try {
exec(`git add . && git commit -m`).then(({ stdout }) => {
console.log(chalk.green(stdout))
})
} catch (err) {
console.log(chalk.red(`err: ${err}`))
}
}).parse(process.argv)
可以看到上面,我们用到了commander,child_exec,chalk,util和fs/promises这几个包
其中
commander是用来获取用户在终端的输入的child_exec是启用子node容器帮助执行node指令的chalk是用来润色我们的输出的- 本质上是借用了console.log('xxxs%','color:red')类似这种的可以书写css的log来实现的
util是将普通异步封装成promise风格的工具包- 这个包不想用的小伙伴可以不用,上面直接通过
child_exec.exec(cmd,(err,res)=>{...})也可
- 这个包不想用的小伙伴可以不用,上面直接通过
fs/promises是fs的promise风格的fs包- 这个也可以直接引入fs,然后使用时用node的callback风格来调用即可
可以看到我们上面通过commender的command('acm')来监听数输入的testcli acm这样的指令。
然后通过action()来触发我们自定义的动作,在action中我们通过exec('git add . && git commit -m')来执行node指令。
并且将返回的结果stdout通过console.log(chalk.green(stdout))来打印出来。
git alias
兄弟们可以自己尝试下类似的功能,当然如果是通过git.alias来实现的话也很简单,只需要在终端输入以下即可
git config -g alias.acm = '!git add . && git commit -m'
如果提示命令过长或者alias.acm绑定不正确的话,可以手动打开git config的全局配置文件.gitconfig,然后在文件的alias下面添上!git add .&& git commit -m即可。
如何找到gitconfig位置?
git config -l --show-origin
结语
往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎嘎~)😄」