【bun】探索使用bun实现一个命令行工具

思考

在我们使用有些npm库(cli)时,我们可以使用某些指令(命令行接口)来使用该库。例如rolluprollup src/main.js -f cjs;或vitevite dev

那么他们时如何实现的?

关于node是实现该功能网上有很多文章,大家可自行查阅。

接下来我们使用bun来实现该功能。其实与nodejs实现原理一致。
我们来实现一个简单的输入输出命令printer;

创建项目

  1. 新建printer文件夹
  2. 使用bun init来初始化项目。

index.ts

#!/usr/bin/env node

import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { readFileSync } from 'node:fs';

// 获取当前文件的目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// 读取 package.json
const packageJson = JSON.parse(
  readFileSync(join(__dirname, 'package.json'), 'utf-8')
);
const version: string = packageJson.version;

function evaluateMathExpression(expr: string): number {
  try {
    return new Function(`return ${expr}`)();
  } catch (error) {
    console.error('无效的数学表达式');
    return NaN;
  }
}

function printHelp(): void {
  console.log(`
打印工具 v${version}

用法:
  printer <文本>          打印文本
  printer --version      显示版本号
  printer --help         显示帮助信息
  printer --math <表达式> 计算数学表达式

示例:
  printer hello world
  printer --math 1+1
  `);
}

type StrategyFunction = (args: string[]) => void;

const strategies: { [key: string]: StrategyFunction } = {
  '--version': (): void => {
    console.log(version);
  },
  
  '--help': printHelp,
  
  '--math': (args: string[]): void => {
    if (args.length < 2) {
      console.error('请提供数学表达式');
      return;
    }
    const expression = args.slice(1).join('');
    const result = evaluateMathExpression(expression);
    if (!isNaN(result)) {
      console.log(result);
    }
  },
  
  default: (args: string[]): void => {
    console.log(args.join(' '));
  }
};

function printArgs(): void {
  const args: string[] = process.argv.slice(2);

  if (args.length === 0) {
    printHelp();
    return;
  }

  const strategy: StrategyFunction = strategies[args[0]] || strategies.default;
  strategy(args);
}

printArgs();

修改package.json

{
  "name": "printer",
  "module": "dist/index.js",
  "version": "1.0.0",
  "type": "module",
  "devDependencies": {
    "@types/bun": "latest"
  },
  "scripts": {
    "start": "bun index.ts",
    "build": "bun build index.ts --target node --outdir dist && cp package.json dist"
  },
  "bin": {
    "printer": "./dist/index.js"
  },
  "peerDependencies": {
    "typescript": "^5.0.0"
  }
}

打包

bun run build

安装到当前项目

bun link

就可以使用啦

printer hello
hello

printer --math 1+1
2

全局使用

npm install -g .

也可发布到npm上面

posted @ 2025-02-08 18:44  demo_you  阅读(128)  评论(0)    收藏  举报