[搭建CLI效率工具] Rollup + TypeScript 搭建CLI工程

2023-10-27

环境搭建

工欲善其事必先利其器,使用Rollup搭建Typescript开发环境。毕竟Typescript是大势所趋并且Rollup相比较webpack对于node模块来说比较优化。

创建项目目录并初始化
mkdir <projectName> && cd <projectName> && yarn init -y
创建基础目录结构
├── bin           #可执行文件目录
│   └── index.js
├── lib           #编译后产物
└──  package.json

bin/index.js

#!/usr/bin/env node
console.log('hello cli')

package.json

{
  "name": "wz-jenkins",
  "version": "1.0.0",
  "description": "terminal call jenkins",
  "main": "lib/index.js",
  "bin": "bin/index.js",
  "repository": "git@github.com:a20070322/wz-jenkins.git",
  "author": "ZhaoZhongYang <z1031839775@gmail.com>",
  "license": "MIT"
}

测试

# 将npm模块链接至全局
npm link 

# 执行命令 package.json中的name
wz-jenkins

# 输出 hello cli

image

搭建rollup环境

为了方便解释包的作用,此处分开下载依赖

# rollup打包工具
yarn add rollup -D

# rollup文件夹清除插件
yarn add rollup-plugin-cleandir -D

# rollup解析及编译TS插件
yarn add @rollup/plugin-typescript -D

# 将json转换为ES6模块
yarn add @rollup/plugin-json -D

# 解析代码中依赖的node_modules
yarn add @rollup/plugin-node-resolve -D

# 
yarn add @rollup/plugin-commonjs 

# 下载ts模块
yarn add typescript -D

# 下载eslist 
yarn add eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser -D

.eslintrc.js
module.exports = {
    parser: '@typescript-eslint/parser',
    extends: [
        'plugin:@typescript-eslint/recommended'
    ],
    parserOptions: {
        project: './tsconfig.json',
        tsconfigRootDir: __dirname,
        ecmaVersion: 2020,
        sourceType: 'module',
        createDefaultProgram: true,
    },
    rules: {

    }
}
tsconfig.json
{
  "compilerOptions": {
    "rootDir": "./",
    "types": ["node"],
    "target": "ESNext",
    "module": "CommonJS",
    "declaration": true,
    "outDir": "lib",
    "strict": true,
    "esModuleInterop": true,
    "pretty": true,
    "resolveJsonModule": true,
    "typeRoots": ["./node_modules/@types/", "./src/typings/"]
  },
  "include": ["src", "types.d.ts"],
  "exclude": ["lib"]
}

rollup.config.js
/** 将json转换为ES6模块 */
const json = require("@rollup/plugin-json");

/** rollup解析及编译TS插件 */
const typescript = require("@rollup/plugin-typescript");

/** 解析代码中依赖的node_modules */
const resolve = require("@rollup/plugin-node-resolve");

/** 将 CommonJS 模块转换为 ES6 的 Rollup 插件 */
const commonjs = require("@rollup/plugin-commonjs");

/** rollup文件夹清除插件 */
const { cleandir } = require("rollup-plugin-cleandir");

module.exports = {
  /** 打包入口文件 */
  input: ["./src/index.ts", "./src/cli.ts"],
  /** 输出配置 */
  output: {
    /** 输出目录 */
    dir: "./lib",
    /** 输出文件为 CommonJS格式 */
    format: "cjs",
  },
  plugins: [
    /** 配置插件 - 每次打包清除目标文件 */
    cleandir("./lib"),
    /** 配置插件 - 将json转换为ES6模块 */
    json(),
    /** 配置插件 - 将json转换为ES6模块 */
    typescript({
      module: "esnext",
      exclude: ["./node_modules/**"],
    }),
    resolve.default({
      extensions: [".js", ".ts", ".json"],
      modulesOnly: true,
      preferredBuiltins: false,
    }),
    commonjs({ extensions: [".js", ".ts", ".json"] }),
  ],
};
package.json

增加了scripts命令

{
  "name": "wz-jenkins",
  "version": "1.0.0",
  "description": "terminal call jenkins",
  "main": "lib/index.js",
  "bin": "bin/index.js",
  "scripts": {
    "lint": "eslint 'src/**/*.{js,ts}' --fix",
    "dev": "rollup -w -c",
    "build": "rollup -c"
  },
  "repository": "git@github.com:a20070322/wz-jenkins.git",
  "author": "ZhaoZhongYang <z1031839775@gmail.com>",
  "license": "MIT",
  "devDependencies": {
    "@rollup/plugin-commonjs": "^21.0.1",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^13.1.3",
    "@rollup/plugin-typescript": "^8.3.0",
    "@typescript-eslint/eslint-plugin": "^5.10.0",
    "@typescript-eslint/parser": "^5.10.0",
    "eslint": "^8.7.0",
    "rollup": "^2.64.0",
    "rollup-plugin-cleandir": "^2.0.0",
    "typescript": "^4.5.4"
  },
  "dependencies": {
    "cac": "^6.7.12"
  }
}

目前工程目录如下
├── LICENSE
├── README.md
├── bin            # 可执行文件目录
│   └── index.js
├── lib            # 编译后产物
│   ├── cli.js
│   └── index.js
├── package.json   
├── rollup.config.js # rollup配置文件
├── src            # 源代码
│   ├── cli.ts     # cli相关函数通过此文件暴露
│   └── index.ts   # 暴露方法,其他项目通过包引用
├── tsconfig.json  # typescript配置文件
└── yarn.lock
代码示例01

命令行工具

下载 cac

yarn add cac
cac 基础使用

src/cli.ts


import cac from "cac";
import { name, version } from "../package.json";

const cli = cac(name);

/** cli命令数组 */
cli.commands = [
  /** 命令行 命令name , 命令描述 , 命令配置 */
  cli.command("", "执行jenkins脚本").action(() => {
    console.log("hello cli");
  }),
];

/** cli-帮助 */
cli.help();

/** cli-版本*/
cli.version(version);

/** 解析命令行参数 */
cli.parse();

/** 异常处理函数 */
const onError = (err: Error): void => {
  console.error(`错误异常: ${err.message}`);
  console.log(err.stack);
  process.exit(1);
};

/** 监听 uncaughtException 异常 */
process.on("uncaughtException", onError);

/** 监听 unhandledRejection 异常 */
process.on("unhandledRejection", onError);

本地监听编译输出 yarn dev

检验成果(终端执行如下命令)
wz-jenkins 
# 输出 hello cli

wz-jenkins -v
# 输出 wz-jenkins/1.0.0 darwin-x64 node-v14.15.1

wz-jenkins -h 

# 输出
# wz-jenkins/1.0.0
# Usage:
# $ wz-jenkins 
# Commands:
#    执行jenkins脚本
# For more info, run any command with the `--help` flag:
#   $ wz-jenkins --help
# Options:
#   -h, --help     Display this message 
#   -v, --version  Display version number
chalk (命令行色彩)
# 下载 chalk
yarn add chalk@4.*

目前只能用4.x版本,更高的版本使用的时候会报错。有更好的解决办法可以评论或私信

src/cli.ts

// 伪代码

// 引入chalk
import chalk from "chalk";

/** cli命令数组 */
cli.commands = [
  /** 增加一个 command */
  cli.command("chalk", "test console color").action(() => {
    console.log(chalk.blue("Hello cli!"));
    console.log(chalk.blue("Hello") + " World" + chalk.red("!"));
    console.log(chalk.blue.bgRed.bold("Hello world!"));
    console.log(chalk.blue("Hello", "World!", "Foo", "bar", "biz", "baz"));
    console.log(chalk.red("Hello", chalk.underline.bgBlue("world") + "!"));
    console.log(
      chalk.green(
        "I am a green line " +
          chalk.blue.underline.bold("https://github.com/") +
          " that becomes green again!"
      )
    );
    console.log(`
      CPU: ${chalk.red("90%")}
      RAM: ${chalk.green("40%")}
      DISK: ${chalk.yellow("70%")}
    `);
    console.log(chalk.rgb(123, 45, 67).underline("Underlined reddish color"));
    console.log(chalk.hex("#DEADED").bold("Bold gray!"));

    const error = chalk.bold.red;
    const warning = chalk.hex("#FFA500");
    console.log(error("Error!"));
    console.log(warning("Warning!"));
    const name = "Sindre";
    console.log(chalk.green("Hello %s"), name);
  }),
];

终端执行命令 wz-jenkins chalk

ora (命令行loading)
# 下载 ora
yarn add ora@5.* 

# 下载 logSymbols
yarn add logSymbols

目前只能用5.x版本,更高的版本编译时候会报错,有更好的解决办法可以评论或私信

src/cli.ts

// 伪代码

// 引入ora
import ora from "ora";
// 引入logSymbols
import logSymbols from "log-symbols";
/** cli命令数组 */
cli.commands = [
  cli.command("ora", "test console color").action(async () => {
    /**
     * 模拟耗时任务
     * @param timer 定时器参数
     * @returns
     */
    const sleep = (timer = 1000) =>
      new Promise<void>((resolve) => {
        setTimeout(() => resolve(), timer);
      });
    /** 开启任务1 loading状态 */
    const spinnerTask1 = ora("run mock task one").start();
    await sleep();
    /** 结束任务1 并且保留内容且改为成功标识 */
    spinnerTask1.stopAndPersist({
      prefixText: logSymbols.success,
    });
    /** 开启任务2 loading状态 */
    const spinnerTask2 = ora("run mock task two").start();
    await sleep();
    /** 结束任务2 并且保留内容且改为错误标识 */
    spinnerTask2.stopAndPersist({
      prefixText: logSymbols.error,
    });
    /** 开启任务3 loading状态 */
    const spinnerTask3 = ora("run mock task three").start();
    await sleep();
    /** 结束任务3 清除浏览器输出 */
    spinnerTask3.stop();
  }),
];

终端执行命令 wz-jenkins ora

cac传送门 | chalk传送门 |
ora传送门 |
logSymbols传送门 | 代码传送门

控制台输出函数封装

src/utils/log.ts

import chalk from "chalk";
import logSymbols from "log-symbols";
import ora from "ora";

/** 获取堆栈信息 */
const getStackTrace = function () {
  const obj: Error = { name: "", message: "" };
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  Error.captureStackTrace(obj, getStackTrace);
  return obj.stack || "";
};

/** 控制台输出封装 */
export const Log = {
  /** info */
  info(...args: unknown[]) {
    console.log(chalk.cyan("Info:"), chalk.cyan(...args));
  },
  /** warn */
  warn(...args: unknown[]) {
    console.log(chalk.yellow("Warn:"), chalk.yellow(...args));
  },
  /** error */
  error(...args: unknown[]) {
    console.log(chalk.red("Error:"), chalk.red(...args));
    const stack = getStackTrace() || "";
    const matchResult = stack.match(/\(.*?\)/g) || [];
    const line = matchResult[1] || "";
    console.log(`${chalk.gray("Error stack:")} ${chalk.gray(line)}`);
  },
  /**
   * loadingPromise
   * @param msg 值
   * @param fn 异步函数
   * @returns
   */
  async loadingPromise<T>(msg: string, fn: () => Promise<T>) {
    const spinner = ora(chalk.cyan(`Loading ${msg}`)).start();
    try {
      const result = await fn();
      spinner.stopAndPersist({
        prefixText: logSymbols.success,
        text: chalk.green(`Success ${msg}`),
      });
      return result;
    } catch (error) {
      spinner.color = "red";
      spinner.stopAndPersist({
        prefixText: logSymbols.error,
        text: chalk.red(`Error ${msg}`),
      });
      throw error;
    }
  },
};

效果如下

ps 后续持续更新
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[搭建CLI效率工具] Rollup + TypeScript 搭建CLI工程 的相关文章

随机推荐

  • pytorch搭建squeezenet网络的整套工程,及其转tensorrt进行cuda加速

    本来 前辈们用caffe搭建了一个squeezenet的工程 用起来也还行 但考虑到caffe的停更后续转trt应用在工程上时可能会有版本的问题所以搭建了一个pytorch版本的 以下的环境搭建不再细说 主要就是pyorch 其余的需要什么
  • 【Java】Java中的多态

    文章目录 一 什么是多态 二 多态实现的条件 三 重写 3 1 什么是重写 3 2 重写和重载的区别 四 向上转型和向下转型 4 1 向上转型 4 2 向下转型 五 多态的优缺点 六 避免在构造方法中调用重写的方法 一 什么是多态 在Jav
  • MySQL多表关联查询

    文章目录 多表查询 用户表 用户角色表 角色表 权限表 角色权限表 表间关系 MySQL连接 关联查询用户表和用户角色表 关联查询用户表 用户角色表和角色表 多表连接 笛卡尔集 外连接
  • 软件测试报告可以包含哪些测试内容?

    软件测试报告可以包含以下测试内容 功能测试 测试软件的基本功能是否实现 是否符合要求 性能测试 测试软件的响应速度 并发能力 稳定性等性能指标 界面测试 测试软件的用户界面是否友好 易于使用 兼容性测试 测试软件在不同的操作系统 浏览器 设
  • Springboot中 @ConfigurationProperties对象 静态方法调用无效

    1 https blog csdn net weixin 43404791 article details 105430606 2 https blog csdn net qq827245563 article details 106296
  • 三行代码求二叉树的节点个数以及二叉树的深度

    二叉树的节点格式如下 struct BinaryTreeNode int m nValue BinaryTreeNode m pLeft BinaryTreeNode m pRight 1 求二叉树的节点个数 这道题比较简单 使用随便一种遍
  • TI DSP TMS320C66x学习笔记之VLIB测试数据(三)

    VLIB是TI提供的针对C6x优化过的视觉库 下载地址 http software dl ti com libs vlib latest index FDS html 提供40多个核心函数 主要实现以下功能 Background Model
  • SpringBoot+vue旅游项目总结

    Springboot vue旅游项目小总结 此项目为一个springboot vue入门级小项目 视频地址为 https www bilibili com video BV1Nt4y127Jh 业务简单 对提升业务能力没什么大的帮助 更多的
  • 开始→运行→输入的命令集锦

    gpedit msc 组策略 sndrec32 录音机 nslookup ip地址侦测器 explorer 打开资源管理器 logoff
  • 最后一位

    题目名称 最后一位 小明选择了一个正整数X 然后把它写在黑板上 然后每一天他会擦掉当前数字的最后一位 直到他擦掉所有数位 在整个过 程中 小明会把所有在黑板上出现过的数字记录下来 然后求出他们的总和sum 例如X 509 在黑板上出现过的数
  • vue打包放服务器显示代码,解决vue-cli3打包代码后,上线服务器后白屏问题

    前沿 因为最近vue刚刚发版了最新版本的vue cli3 而最近刚刚好有个项目要迁移到vue 所以经过讨论 大家一起入坑VUE 然后我也刚好可以练手刚学一周的vue 结合TypeScript和vuex等全家桶的框架 后期 噗呲噗呲的大家在开
  • C++实现快速排序(源代码)

    快速排序的基本思想是 通过一趟排序将要排序的数据分割成独立的两部分 其中一部分的所有数据都比另外一部分的所有数据都要小 然后再按此方法对这两部分数据分别进行快速排序 整个排序过程可以递归进行 以此达到整个数据变成有序序列 快速排序是一种不稳
  • 一阶滞后环节matlab,一个一阶惯性带有滞后环节的PID仿真程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 我照着网上的程序自己改出来的程序是这样的 clc clear ts 0 001 采样时间 sys tf 53 19926 100 ioDelay 540 tf是传递函数 用来实现G s 在自动控
  • 一种基于强化学习的自动变道机动方法

    文章目录 摘要 前言 相关的工作 方法论 动作空间 奖励函数设计 Q学习 仿真结果 结论 摘要 变道是一项至关重要的车辆操作 需要与周围车辆协调 建立在基于规则的模型上的自动换道功能可能在预定义的操作条件下表现良好 但在遇到意外情况时可能容
  • 海思芯片pcie启动——pcie_mcc驱动框架的booter程序分析

    1 booter程序介绍 1 源码目录 pcie mcc multi boot example boot test c 2 调用命令 booter start device 3 booter程序的作用 在主片将pcie启动相关的驱动加载完成
  • centos7 安装jdk1.8

    一 安装环境 虚拟机centos7 二 安装步骤 linux环境下软件的安装有两种类型 yum install 和wget gz 安装包的格式 建议不管安装什么软件方式 能用wget解压安装包安装就用这种方式安装 1 下载安装包 wget
  • BUUCTF【Web】Secret File

    知识点 文件包含漏洞 PHP伪协议 进入靶场后 发现是一个文字界面没有任何特点 习惯性的右键查看源代码 发现有一个PHP文件 点击进行访问后 发现有一个链接但是点击链接后没有发现任何东西 此时右键查看原代码也没有发现东西 但是可以肯定的是突
  • ERP收付款的操作与设计--开源软件诞生22

    赤龙ERP收款付款讲解 第22篇 用日志记录 开源软件 的诞生 进入地址 点亮星星 祈盼着一个鼓励 博主开源地址 码云 https gitee com redragon redragon erp GitHub https github co
  • 4,引擎初始化--(5)初始化actor--5,初始化各个关卡中的各个actor-PostInitializeComponents()

    PostInitializeComponents 是actor最初处于完整状态的地方 所以 在这里经常编写actor在游戏开始时的初始化相关代码 此时 loadmap 加载完毕 actor加载完毕并初始化 world处于可玩状态 同时也有了
  • [搭建CLI效率工具] Rollup + TypeScript 搭建CLI工程

    环境搭建 工欲善其事必先利其器 使用Rollup搭建Typescript开发环境 毕竟Typescript是大势所趋并且Rollup相比较webpack对于node模块来说比较优化 创建项目目录并初始化 mkdir