Создание собственных команд CLI

Quasar Framework предоставляет мощные возможности для расширения стандартного CLI через создание собственных команд. Эти команды позволяют автоматизировать задачи, интегрировать сторонние инструменты и оптимизировать процесс разработки.

1. Архитектура команд CLI

Каждая пользовательская команда CLI представляет собой отдельный модуль, расположенный в папке проекта src/commands или в директории, указанной в конфигурации Quasar CLI. Основные элементы команды:

  • Имя команды — уникальный идентификатор, по которому CLI будет вызывать команду.
  • Описание — строка, поясняющая назначение команды.
  • Опции — объект с перечислением всех параметров, которые поддерживает команда.
  • Хендлер — функция, выполняющая основную логику команды.

Структура файла команды обычно выглядит так:

module.exports = function (/* ctx */) {
  return {
    name: 'my-command',
    description: 'Пример пользовательской команды',
    options: {
      '--example': 'Описание опции example'
    },
    handler (args, api) {
      // Реализация команды
    }
  }
}
  • args — объект, содержащий значения переданных параметров.
  • api — объект с методами Quasar CLI для взаимодействия с проектом, генерации файлов, выполнения скриптов и др.

2. Регистрация команды

Для того чтобы CLI распознавал новую команду, необходимо зарегистрировать её в конфигурации Quasar. Это делается через экспорт массива команд в quasar.extensions.json или подключение через quasar.conf.js. Пример подключения команды через конфигурационный файл:

// quasar.conf.js
module.exports = function (/* ctx */) {
  return {
    extendCli (cli) {
      cli.registerCommand(require('./src/commands/my-command'))
    }
  }
}

После регистрации команда становится доступной через терминал как:

quasar my-command --example

3. Опции и аргументы команд

Quasar CLI поддерживает две категории параметров:

  • Флаги — короткие или длинные ключи, определяющие поведение команды, например --prod или -p.
  • Позиционные аргументы — значения, передаваемые без ключа, например имя файла или название компонента.

Пример обработки флагов и аргументов:

handler (args) {
  if (args['--prod']) {
    console.log('Сборка для продакшена включена')
  }

  const name = args._[0] // первый позиционный аргумент
  console.log(`Имя объекта: ${name}`)
}

Ключевой момент: все позиционные аргументы Quasar CLI помещает в массив args._.

4. Использование API Quasar в командах

API Quasar CLI предоставляет набор утилит, доступных в объекте api, таких как:

  • api.prompts — интерактивные запросы к пользователю (списки, подтверждения, ввод текста).
  • api.resolve — получение абсолютных путей к файлам проекта.
  • api.addFile — генерация новых файлов или перезапись существующих.
  • api.runScript — запуск внешних скриптов или npm-команд.

Пример использования интерактивного запроса:

async handler (args, api) {
  const response = await api.prompts({
    type: 'input',
    name: 'componentName',
    message: 'Введите имя нового компонента'
  })

  console.log(`Создаем компонент с именем: ${response.componentName}`)
}

5. Генерация файлов через команды

Частая задача пользовательских команд — автоматическое создание шаблонов компонентов или страниц. Используется метод api.addFile:

api.addFile({
  filename: `src/components/${componentName}.vue`,
  content: `<template>\n  <div>${componentName}</div>\n</template>\n<script>\nexport default {\n  name: '${componentName}'\n}\n</script>`
})

Особенности:

  • filename — путь к создаваемому файлу относительно корня проекта.
  • content — текстовое содержимое файла.
  • api.addFile автоматически создаст директории, если они отсутствуют.

6. Обработка ошибок и логирование

Quasar CLI рекомендует использовать console.log, console.error и console.warn для вывода информации и ошибок. Для критических ошибок можно выбросить исключение:

if (!componentName) {
  throw new Error('Имя компонента обязательно')
}

7. Асинхронные команды

Все современные команды CLI должны поддерживать асинхронные операции. Хендлер может быть async и использовать await для работы с файловой системой или внешними API.

async handler (args, api) {
  const data = await fetchSomeData()
  await api.addFile({ filename: 'data.json', content: JSON.stringify(data) })
}

8. Советы по организации команд

  • Разделять команды по функциональности: генерация, сборка, проверка.
  • Создавать отдельные утилиты для повторяющейся логики.
  • Документировать каждую команду и её опции в описании.

Эта структура позволяет создавать мощные расширения CLI, интегрированные с проектом, упрощает автоматизацию процессов и снижает вероятность ошибок при ручной работе с проектом.