【脚手架】 如何优雅地写npm包中的bin命令?

95 阅读1分钟

背景

对于一个包,我们可能有很多条bin命令,并且这些命令有各种各样不同的参数。如果采取暴力枚举法逐一罗列的话,代码会显得又笨又重,逻辑混乱。

  • bin命令众多
  • 需要编程

其实,完全可以用一种优雅的方式来实现。也就是编程的想法,用配置文件以及函数编程的方式去实现。

package.json中的bin字段

package.json中定义入口文件:

// package.json

"bin": {
    "vite": "bin/index.js"
 }

bin入口文件

在bin入口文件bin/index.js对参数进行简单的处理与清洗。并且嵌入命令运行perforce的监测:

// bin/index.js

#!/usr/bin/env node

// performan性能监测
import { performance } from 'node:perf_hooks'
global.__vite_start_time = performance.now()

function start() {
  return import('../dist/cli.js')
}

// 对命令行输入参数 process.argv进行处理与清洗
if (...) {
  // do something
} else {
  start()
}

对输入命令进行处理

主要的命令处理用cac这个包进行实现,用法官方文档 写得很清楚了。 以下为具体的用法:

import { cac } from 'cac'
import { VERSION } from './constants'
const cli = cac('colatest')

cli
  .option('-c, --config <file>', `[string] use specified config file`)
  .option('--base <path>', `[string] public base path (default: /)`)
  .option('-l, --logLevel <level>', `[string] info | warn | error | silent`)
  .option('--clearScreen', `[boolean] allow/disable clear screen when logging`)
  .option('-d, --debug [feat]', `[string | boolean] show debug logs`)
  .option('-f, --filter <filter>', `[string] filter debug logs`)
  .option('-m, --mode <mode>', `[string] set env mode`)

cli
  .command('[root]', 'start dev server') // default command
  .alias('serve') // the command is called 'serve' in Vite's API
  .alias('dev') // alias to align with the script name
 
 
cli.help()
cli.version(VERSION)

// 注意,最后要解析
cli.parse()