View on GitHub

Yinjie - GitHub.io

Welcome to the Yinjie's notes

node cli 开发的 git 快捷命令

虽然本文标题落脚点是 快捷命令,但重点是以此为例,简单说一下写 node shell 的写法。

作为一个前端码农,相对开发后台的同学,工作中我们可能会比较少的接触到系统运维相关的知识,不过这也不会成为我们使用这类技术的障碍,或是不使用它的理由。 在前端工程化程度越来越高的今天,相信你以后很快会用到的。至少,我们可以先把自己的开发环境打理的更加高效点也是很不错的。

一个简单的 node cli

我们经常通过 npm 安装一些 ‘模块’,其中用一些是自带命令行工具的,比如 less 之类的。 这是怎么实现的呢,其实很简单。往下看,保你5分钟上手 node cli 开发。

  1. 新建一个文件夹,假设:cli-demo
  2. 进入这个文件夹;
  3. 初始化 package.json :

建议用 npm init,这样生成的 package.json 比较标准。过程就不说了,可以先怎么方便怎么来。

  1. 改造 package.json:

这是第一个重点,生成的 package.json 是针对普通 node_module 的,不满足 cli 的要求,我们需要改造一下:

  • 添加 "bin": { "cli-demo": "bin/index.js" } 这个是命令行工具模式的核心属性,有了它,才可以直接作为工具执行。它的值是一个对象,其中 key 是将来的工具名,value 是这个工具所对应执行的 js 文件。可以设置多个。
  • 添加 "preferGlobal": true。添加这个属性是为了其它用户在安装你的工具时,如果没有添加 -g or --global 参数时,会出现提示,指出这个模块是被设计成命令行工具的,需要全局安装。
  • 如果你的模块只能是作为命令行工具,不支持常规的 node_module 调用,如 const less = require('less'),记得把这个属性去掉:"main": "cli-demo"

以下是示例:

{
  "name": "cli-demo",
  "version": "0.1.0",
  "description": "A simple node cli demo.",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "preferGlobal": true,
  "bin": {
    "cli-demo": "bin/index.js"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "author": "author",
  "license": "MIT"
}
  1. 添加 bin/index.js 脚本文件:
#! /usr/bin/env node

console.log('This is a cli ~');

注意:

  • 路径可是自由确定;
  • 第一行的 #! /usr/bin/env node 不能去掉,这可不是注释什么的,知道 shell 脚本知识的人明白它的意义,可以自己去了解一下;
  • 不要用高级语法,很多高级语法在 node v4 以上的环境下不支持,当然你通过 babel 等方法编译成的目标文件就另当别论了。
  1. 注册这个脚本到系统工具:

可以直接用 npm link 命令将这个简易脚本注册成系统命令行工具。 执行后,你就可以直接在命令中用它了:

$ cli-demo
This is a cli ~

就这么简单~

命令行参数

工具一般都有很多的参数提供各类的功能。我们可以直接通过执行环境变量 process 来获取:

process.argv
$ cli-demo -a -b --c /d
/*
 * process.argv:
 [ 'node/v6.10.3/bin/node',
  'node/v6.10.3/bin/cli-demo',
  '-a',
  '-b',
  '--c',
  '/d' ]
 */

了解了以上两点,你就可以自由发挥了。

git 命令

之前写过一个 git 的 bash shell 脚本,现在可以用“本专业”的 node 来写了,以下是一个常用的 git pull 快捷命令,其它的类似。

其中截取分支名称的一行,因各人不同的 git 命令行结果而异,自行调整。

#! /usr/bin/env node

const execSync = require('child_process').execSync;

try {
    const str1 = execSync('git status', {encoding: 'utf8'});
    const re = str1.match(/^On branch (.+)\s/);
    console.log('你现在所在分支:' + re[1] + '\n');
    const str2 = execSync('git pull origin ' + re[1], {encoding: 'utf8'});
    console.log(str2);
} catch (err) {
    console.log('execute error:');
    console.log(err.toString());
}

附录

再外送一个通用的 bash 脚本:

#!/bin/bash

branch=`git status | head -n 1 | awk -F ' ' '{ print $2 }'`;
echo '当前分支:'$branch;
commit_id=`git log | head -n 1 | awk -F ' ' '{ print $2 }'`;
echo 'local commit id: '$commit_id;
git push origin $branch;