终端 UI
Ace 提供终端 UI 原语来显示日志、格式化输出、渲染表格和动画,由 @poppinss/cliui 提供支持。
日志记录器
日志记录器组件用于在终端中显示日志消息。
日志方法
命令类使用 this.logger 属性公开日志记录器实例。您可以使用不同的方法来显示不同类型的日志消息。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
this.logger.debug('Debug message')
this.logger.info('Info message')
this.logger.success('Success message')
this.logger.warning('Warning message')
this.logger.error('Error message')
this.logger.fatal('Fatal message')
}
}添加前缀和后缀
您可以使用 prefix 和 suffix 选项为日志消息添加前缀和后缀。
ts
this.logger.info('Downloading files', {
prefix: '[1/3]',
suffix: '50%'
})加载动画
logger.await 方法在日志消息旁边显示加载动画。您可以使用此方法指示长时间运行的操作。
ts
const loader = this.logger.await('Downloading files')
// 下载完成后
loader.stop()您还可以更新消息。
ts
const loader = this.logger.await('Downloading files')
// 更新消息
loader.update('Almost done')
// 下载完成后
loader.stop()日志记录器操作
logger.action 方法用于显示操作及其状态。这对于显示应用程序中执行的操作列表很有用。
ts
this.logger.action('Creating config file').succeeded()
this.logger.action('Updating package.json').succeeded()
this.logger.action('Installing dependencies').failed('Network error')
this.logger.action('Cleanup').skipped('Not needed')颜色
this.colors 属性公开 @poppinss/colors 模块来格式化带有 ANSI 颜色的文本。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
console.log(this.colors.red('This is red'))
console.log(this.colors.green('This is green'))
console.log(this.colors.bgRed().white('White text on red background'))
console.log(this.colors.bold().underline('Bold and underlined'))
}
}可用的颜色方法:
black、red、green、yellow、blue、magenta、cyan、white、graybgBlack、bgRed、bgGreen、bgYellow、bgBlue、bgMagenta、bgCyan、bgWhitedim、bold、hidden、italic、underline、strikethrough、inverse
表格
this.ui.table 方法用于在终端中渲染表格。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
const table = this.ui.table()
table.head(['Name', 'Age', 'City'])
table.row(['John', '30', 'New York'])
table.row(['Jane', '25', 'Los Angeles'])
table.row(['Bob', '35', 'Chicago'])
table.render()
}
}自动计算列
您可以使用 fullWidth 方法使表格占据整个终端宽度,并使用 fluidColumnIndex 方法指定哪个列应占据剩余空间。
ts
const table = this.ui.table()
table.head(['File', 'Size', 'Status'])
table.fullWidth()
table.fluidColumnIndex(0) // File 列将占据剩余空间
table.row(['package.json', '2KB', 'OK'])
table.row(['node_modules/express/package.json', '1KB', 'OK'])
table.render()贴纸
this.ui.sticker 方法用于在终端中打印带边框的消息框。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
this.ui.sticker()
.heading('Application ready')
.add('Local: http://localhost:3333')
.add('Network: http://192.168.1.100:3333')
.render()
}
}指令
this.ui.instructions 方法用于在终端中显示指令列表。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
this.ui.instructions()
.heading('Getting Started')
.add('Run npm install')
.add('Run npm run dev')
.add('Open http://localhost:3333')
.render()
}
}任务
this.ui.tasks 方法用于在终端中渲染带有动画进度的任务列表。
ts
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
const tasks = this.ui.tasks()
await tasks
.add('Installing dependencies', async (task) => {
await someAsyncOperation()
return task.completed()
})
.add('Compiling TypeScript', async (task) => {
await anotherAsyncOperation()
return task.completed()
})
.add('Running tests', async (task) => {
await runTests()
return task.completed()
})
.run()
}
}任务状态
每个任务可以返回以下状态之一:
task.completed():任务成功完成task.failed(error):任务失败并显示错误消息task.skipped(reason):任务被跳过并显示原因
ts
await tasks
.add('Check prerequisites', async (task) => {
const isValid = await checkPrerequisites()
if (!isValid) {
return task.failed('Prerequisites not met')
}
return task.completed()
})
.add('Optional step', async (task) => {
if (!needsOptionalStep) {
return task.skipped('Not required')
}
await performOptionalStep()
return task.completed()
})
.run()详细模式
您可以通过将 verbose 选项传递给 tasks 方法来启用详细模式。在详细模式下,任务的所有输出都会显示在终端中。
ts
const tasks = this.ui.tasks({ verbose: true })更新任务消息
您可以在执行期间使用 task.update 方法更新任务消息。
ts
await tasks
.add('Downloading files', async (task) => {
task.update('Downloading file 1/3')
await downloadFile1()
task.update('Downloading file 2/3')
await downloadFile2()
task.update('Downloading file 3/3')
await downloadFile3()
return task.completed()
})
.run()