npm 命令行工具开发指南

我们在前端开发中会经常用到命令行工具,比如@babel/clivue-clicreate-react-app 等等。那么如何创建一个npm 命令行工具呢?其实很简单的,仅需要几步即可。

创建

1 初始化npm项目

npm init
package name: (cli) gogocode-cli
version: (1.0.0) 
description: my-first-cli
entry point: (index.js) 
keywords: npm cli
author: super man

2 配置bin字段

npm init 后会生成一个package.json文件,在该文件中添加一个bin字段,bin字段的key就是你的命令(gogocode),value指向相对于package.json的路径(index.js),不同的key对应不同的命令。关于 bin 字段更多信息请参考文档

{
  "name": "gogocode-cli",
  "version": "1.0.0",
  "description": "my-first-cli",
  "bin": {
    "gogocode": "index.js"
  }
}

3 创建index.js文件

在项目根目录创建index.js文件。下面是index.js文件内容:使用console.log() 函数来输出命令行返回信息。

 #!/usr/bin/env node
 console.log('Hello, world!');

注意:第一行一定要添加脚本来指定运行环境(#!/usr/bin/env node)

4 打包发布

4.1 发布

  • 在项目根目录执行npm pulish 命令。按照系统提示操作,即可将你的命令行工具发布到 npmjs 平台。期间需要注册npm账号,可自行百度。
npm publish
  • 打包完成之后,就能在npmjs官网看到你发布的npm包了。

image.png

4.2 验证

  1. 全局安装 npm 包
npm install gogocode-cli -g
  1. 执行命令
gogocode
  1. 正确输出 “Hello,World!” 😊

image.png

进阶&工具

上面只是把npm命令行工具从准备到发布简单跑通,如果需要构建复杂的npm命令行应用还需要借助一些辅助开发包。下面介绍两个比较常用npm包: commanderterminal-kit

Commander

  • commander用于组织命令行指令(command)和参数(option),它主要负责对命令行的输入信息进行处理。

    • command 可以理解为“指令”用于定义一个代码逻辑。一般指的是命令行工具第一个空格和第二个空格之间的文本。比如: npm init,其中init就是一个command。一个命令行工具可以支持多个指令输入。
    • option 可以理解为“指令”的函数入参。以 “-” 或者 “--” 开头,比如:ls -a,其中-a就是一个参数,代表列出全部文件。注意:“-” 为 “--”的简写形式。
  • 下面以我们最近开发的一个命令行工具 gogocode-cli 为例,为大家具体讲解下 commander 如何使用。

    • 首先我们看下入口文件index.js的代码:
#!/usr/bin/env node
const program = require('commander');
const term = require('terminal-kit').terminal;
const pkg = require('./package.json');
//插件加载及执行逻辑
const transform = require('./transform');
//初始化插件项目逻辑
const init = require('./commands/init');

// 配置command
program
.command(`init`)
.description('初始化一个插件sample项目')
.action((options) => {
    init(options);
});

// 配置options
program.option('-t, --transform <package name or path>', '插件路径或者npm包名称,支持多个插件,逗号分隔')
.option('-o, --out <path>', '输出文件路径')
.option('-s, --src <path>', '需要转换的源文件路径')
.action((options) => {
    return transform(options);
});

// 配置 cli 信息,版本、cli说明等
program
.version(pkg.version)
.description(term.blue('GoGoCode  代码转换从未如此简单  https://gogocode.io'));
console.log();

// 接管命令行输入,参数处理
program.parse(process.argv);
  • 上面的代码我们可以看出:gogocode-cli 对外支持 init 指令(command) 和 -t,-o,-s 等参数(option)定义,具体定义如下:
参数|指令 缩写 参数说明 类型
init init 初始化一个插件sample项目 command
--src -s 需要转换的源文件路径 option
--transform=FILE/npm package -t 插件路径或者npm包名称 option
--out -o 输出文件路径 option
  • 我们执行一下 index.js:
node ./index.js

结果如下:

image.png

我们可以看到 commander 自动帮我们处理指令和参数显示及逻辑拆分问题,同时自动添加 -V,-h 两个option。可以说非常方便。

terminal-kit

terminal-kit 是一个功能强大的命令行输出工具,支持文本样式、table、menu、进度条等多种交互形式。下面简单介绍一下几个常用功能。

  1. 字体颜色,输出蓝色文本
const term = require('terminal-kit').terminal;
term.blue('GoGoCode  代码转换从未如此简单  https://gogocode.io');
  1. table表格输出
const term = require('terminal-kit').terminal;
term.table([
    ['header #1', 'header #2', 'header #3'],
    ['row #1', 'a much bigger cell, a much bigger cell, a much bigger cell... ', 'cell']
], {
    hasBorder: false,
    contentHasMarkup: true,
    textAttr: { bgColor: 'default' },
    firstCellTextAttr: { bgColor: 'blue' },
    firstRowTextAttr: { bgColor: 'yellow' },
    firstColumnTextAttr: { bgColor: 'red' },
    checkerEvenCellTextAttr: { bgColor: 'gray' },
    width: 60,
    fit: true   // Activate all expand/shrink + wordWrap
}
);
  1. Yes or No 询问
const term = require('terminal-kit').terminal;

term('Do you like gogocode? [Y|n]\n');

term.yesOrNo({ yes: ['y', 'ENTER'], no: ['n'] }, function (error, result) {

    if (result) {
        term.green("'Yes' detected! Good bye!\n");
        process.exit();
    }
    else {
        term.red("'No' detected, are you sure?\n");
    }
});

调试


命令行工具开发过程中该如何进行Debug呢?我们可以这样操作。

  1. 将vscode(最新版本)内置终端(terminal)切换到 JavaScript Debug Terminal
  2. 使用vscode内置断点功能,打断点。
  3. JavaScript Debug Terminal 中执行 node ./index.js 即可debug


debug.gif

gogocode

以上npm命令行开发经验都是小编在开发 gogocode-cli 过程中总结而来。gogocode-cligogocode 的命令行工具。那 gogocode 是什么东东呢?引用一下官方介绍:

GoGoCode是一个操作AST的工具,可以降低使用AST的门槛,帮助开发者从繁琐的AST操作中解放出来,更专注于代码分析转换逻辑的开发。简单的替换甚至不用学习AST,而初步学习了AST节点结构(可参考AST查看器)后就可以完成更复杂的分析转换。

gogocode的官方文档 gogocode.io/zh/docs/spe…


gogocode可以说是一个上手快、使用爽的代码转换工具。

gogocode转换插件

既然gogocode这么好用,那么我们如何使用gogocode来编写转换插件呢?下面为大家讲解下吧:

插件初始化

  • 首先需要安装gogocode-cli
npm install gogocode-cli -g
  • 之后执行 “gogocode init” 来初始化一个插件项目
gogocode init

插件项目结构

gogocode init 初始化后的插件目录,是一个标准的npm项目。项目的主入口配置在package.json的main节点。

image.png

上图截图我们可以看到,插件项目转换逻辑入口为transform.js,具体定义如下:

/**
 * 转换入口导出一个函数,按照如下函数签名
 * @param {*} fileInfo 包含 source 和 path 属性。source为待转换文本,path为路径
 * @param {*} api 包含 gogocode 作为转换工具
 * @param {*} options 其他 option 由此传入
 * @returns {string} 返回转换后的代码
 */
module.exports = function(fileInfo, api, options) {
  const sourceCode = fileInfo.source;
  const $ = api.gogocode;
  return $(sourceCode)
    .replace('const a = $_$', 'const a = 2')
    .generate();
};


我们的转换逻辑需要定义在上面的函数中

转换逻辑执行

gogocode-cli 执行 js文件

转换逻辑可以以js文件的形式执行,下面是具体命令:

gogocode -s ./test/input.vue -t ./transform.js -o out.vue

其中,gogocode-cli 命令行参数定义可以参考上面 commander 章节中gogocode-cli的参数定义。

gogocode-cli 执行 npm包


如果想把自己写好的插件分享给大家,可以直接把这个项目打包成npm包。
gogocode-cli同时也支持运行npm转换逻辑的功能。
例如我们发布了一个“vue2-to-3”的npm插件。可以执行下面命令,来运行npm包里面的转换逻辑。

gogocode -s ./test/input.vue -t ./vue2-to-3 -o out.vue

GoGoCode 相关链接

GoGoCode的Github仓库(新项目求star _
https://github.com/thx/gogocode

GoGoCode的官网
https://gogocode.io/

可以来 playground 快速体验一下
https://play.gogocode.io/


阿里妈妈出的新工具,给批量修改项目代码减轻了痛苦
「GoGoCode 实战」一口气学会 30 个 AST 代码替换小诀窍
0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题
GoGoCode协助清理代码中的「垃圾」

posted @ 2021-04-27 17:26  无敌第三代  阅读(948)  评论(0编辑  收藏  举报