name: ora-spinner-integration description: 集成ora加载动画,提供一致的CLI进度反馈样式、Promise处理和状态更新。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep
Ora加载动画集成
集成ora加载动画,为CLI提供一致的进度反馈。
功能
- 配置ora加载动画样式
- 创建基于Promise的加载动画
- 设置加载动画序列
- 实现状态转换
- 创建自定义加载动画类型
- 生成加载动画工具函数
使用场景
在以下情况调用此技能:
- 为CLI添加加载指示器
- 在异步操作期间显示进度
- 创建一致的加载动画样式
- 实现状态转换
输入参数
| 参数 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
| language | string | 是 | 目标语言(typescript, javascript) |
| style | object | 否 | 加载动画样式选项 |
| spinners | array | 否 | 自定义加载动画定义 |
生成模式
TypeScript加载动画工具函数
import ora, { Ora, Options } from 'ora';
import chalk from 'chalk';
// 加载动画配置
const defaultOptions: Options = {
color: 'cyan',
spinner: 'dots',
prefixText: '',
};
// 创建具有一致样式的加载动画
export function createSpinner(text: string, options?: Partial<Options>): Ora {
return ora({
...defaultOptions,
...options,
text,
});
}
// 带Promise的加载动画
export async function withSpinner<T>(
text: string,
fn: () => Promise<T>,
options?: {
successText?: string | ((result: T) => string);
failText?: string | ((error: Error) => string);
}
): Promise<T> {
const spinner = createSpinner(text);
spinner.start();
try {
const result = await fn();
const successText = typeof options?.successText === 'function'
? options.successText(result)
: options?.successText || text;
spinner.succeed(successText);
return result;
} catch (error) {
const failText = typeof options?.failText === 'function'
? options.failText(error as Error)
: options?.failText || `失败: ${(error as Error).message}`;
spinner.fail(failText);
throw error;
}
}
// 顺序加载动画
export async function withSequentialSpinners<T>(
steps: Array<{
text: string;
fn: () => Promise<any>;
successText?: string;
}>
): Promise<T[]> {
const results: T[] = [];
for (const step of steps) {
const result = await withSpinner(step.text, step.fn, {
successText: step.successText,
});
results.push(result);
}
return results;
}
// 多行加载动画状态
export class TaskSpinner {
private spinner: Ora;
private tasks: Map<string, 'pending' | 'running' | 'done' | 'failed'>;
constructor(title: string) {
this.spinner = createSpinner(title);
this.tasks = new Map();
}
addTask(id: string): void {
this.tasks.set(id, 'pending');
this.updateDisplay();
}
startTask(id: string): void {
this.tasks.set(id, 'running');
this.updateDisplay();
}
completeTask(id: string): void {
this.tasks.set(id, 'done');
this.updateDisplay();
}
failTask(id: string): void {
this.tasks.set(id, 'failed');
this.updateDisplay();
}
private updateDisplay(): void {
const lines = Array.from(this.tasks.entries()).map(([id, status]) => {
const icon = {
pending: chalk.gray('○'),
running: chalk.cyan('◐'),
done: chalk.green('●'),
failed: chalk.red('✗'),
}[status];
return ` ${icon} ${id}`;
});
this.spinner.text = '
' + lines.join('
');
}
start(): void {
this.spinner.start();
}
stop(): void {
const failed = Array.from(this.tasks.values()).some(s => s === 'failed');
if (failed) {
this.spinner.fail('任务完成但有错误');
} else {
this.spinner.succeed('所有任务完成');
}
}
}
使用示例
// 简单加载动画
const spinner = createSpinner('加载中...');
spinner.start();
// ... 执行工作
spinner.succeed('加载完成!');
// Promise包装器
const data = await withSpinner(
'获取数据中...',
() => fetchData(),
{ successText: (data) => `已加载 ${data.length} 个项目` }
);
// 顺序步骤
await withSequentialSpinners([
{ text: '安装依赖中...', fn: () => installDeps() },
{ text: '构建项目中...', fn: () => build() },
{ text: '运行测试中...', fn: () => test() },
]);
// 任务跟踪
const tasks = new TaskSpinner('处理文件中');
tasks.addTask('file1.ts');
tasks.addTask('file2.ts');
tasks.start();
tasks.startTask('file1.ts');
// ... 处理
tasks.completeTask('file1.ts');
tasks.startTask('file2.ts');
tasks.completeTask('file2.ts');
tasks.stop();
依赖项
{
"dependencies": {
"ora": "^7.0.0",
"chalk": "^5.0.0"
}
}
目标流程
- 进度状态指示器
- CLI输出格式化
- CLI应用程序引导