Оглавление
В какой-то момент своей карьеры frontend-разработчика я столкнулся с ситуацией, когда рутинные задачи начали занимать слишком много времени. Эти задачи были однотипными, повторяющимися, и, честно говоря, скучными. Постоянная настройка окружения, сборка проекта, обновление зависимостей, запуск тестов – всё это требовало ручного вмешательства каждый раз. Тогда я подумал: «Почему бы не автоматизировать это через свою собственную CLI (Command Line Interface)?»
Зачем вообще нужна своя CLI?
На первый взгляд, кажется, что разработка собственной CLI — это излишество, особенно когда существуют готовые инструменты, такие как npm
, yarn
, webpack
и множество других. Однако, сталкиваясь с проектами, которые требуют специфической настройки или выполнения уникальных команд, я пришёл к выводу, что стандартные инструменты не всегда дают достаточную гибкость. Некоторые команды требовали множественных шагов, которых можно было избежать. К тому же, CLI-интерфейс позволил бы мне улучшить продуктивность команды, минимизировав количество ошибок при выполнении рутинных задач.
Проблема на работе
Я работал над проектом, в котором команда разработчиков постоянно переключалась между разными ветками, окружениями и версиями зависимостей. Каждый раз приходилось вручную менять настройки, обновлять зависимости и заново запускать сборку проекта. Это было неудобно и занимало лишнее время. Особенно когда проект был тяжелым и каждое обновление зависимостей или тесты занимали несколько минут.
Путь к решению: создание собственной CLI
Я решил, что пора решить эту проблему раз и навсегда, и занялся созданием своей CLI, которая бы автоматизировала большую часть рутинных процессов. В процессе работы над инструментом я прошёл через несколько ключевых шагов:
1. Определение функциональности
Первым делом я решил, какие именно задачи должна решать моя CLI. Основные требования были следующие:
— Автоматическое переключение веток и пересборка проекта;
— Проверка и обновление зависимостей;
— Запуск тестов и деплой;
— Создание конфигураций для разных окружений (staging, production).
2. Выбор инструментов
Я выбрал Node.js и пакет Commander.js
для создания интерфейса командной строки. Этот инструмент оказался достаточно гибким и позволил легко добавлять команды и опции. Альтернативой мог быть yargs
, но Commander.js
показался мне более удобным для нужд проекта.
const { exec } = require('child_process');
const { program } = require('commander');
program
.command('switch-branch ')
.description('Переключение на указанную ветку и пересборка проекта')
.action((branch) => {
exec(`git checkout ${branch}`, (error, stdout, stderr) => {
if (error) {
console.error(`Ошибка переключения ветки: ${error.message}`);
return;
}
console.log(`Переключено на ветку: ${branch}`);
console.log('Запуск пересборки...');
exec('npm run build', (buildError) => {
if (buildError) {
console.error(`Ошибка сборки: ${buildError.message}`);
return;
}
console.log('Проект успешно собран.');
});
});
});
program.parse(process.argv);
3. Реализация автоматизации
Создание своей CLI требует чёткого понимания того, какие задачи мы хотим автоматизировать и как они будут выполняться. В моём случае основная задача заключалась в том, чтобы автоматизировать процесс переключения веток в Git и пересборки проекта. Этот процесс в нашем проекте выглядел следующим образом:
1. Разработчик выбирал нужную ветку в Git.
2. Выполнял команду git checkout <branch>
для переключения на неё.
3. Затем запускал сборку проекта через npm run build
.
4. Если проект был сложным, каждый раз приходилось проверять, установлены ли все зависимости, и при необходимости обновлять их с помощью npm install
.
Каждый раз проходить все эти шаги вручную было неудобно и занимало время. Решение состояло в том, чтобы объединить эти шаги в одну CLI-команду.
Структура команды
Команда в CLI должна:
— Принимать название ветки, на которую нужно переключиться;
— Проверить, нет ли ошибок при переключении;
— Запускать сборку проекта после успешного переключения;
— Обрабатывать возможные ошибки, чтобы разработчик сразу видел, что пошло не так.
Детальный разбор кода
Давайте разберём код по частям и добавим больше деталей.
const { exec } = require('child_process');
const { program } = require('commander');
Для выполнения команд в терминале используется встроенный модуль Node.js child_process
. Метод exec
позволяет запускать команды в командной строке прямо из нашего скрипта. Пакет commander
помогает организовать интерфейс командной строки и позволяет легко добавлять команды с описанием и параметрами.
Переключение ветки
Начнём с команды для переключения ветки:
program
.command('switch-branch ') // Команда принимает аргумент branch
.description('Переключение на указанную ветку и пересборка проекта') // Описание команды
.action((branch) => {
exec(`git checkout ${branch}`, (error, stdout, stderr) => { // Запуск команды git checkout
if (error) {
console.error(`Ошибка переключения ветки: ${error.message}`); // Обработка ошибки
return;
}
console.log(`Переключено на ветку: ${branch}`); // Вывод успеха в консоль
На этом этапе программа:
1. Принимает название ветки от пользователя.
2. Вызывает команду git checkout <branch>
для переключения на нужную ветку.
3. Проверяет, успешно ли произошло переключение. Если произошла ошибка (например, ветка не существует или имеются несохранённые изменения), она выводит сообщение об ошибке и останавливается.
В случае успеха программа выводит сообщение о том, что переключение произошло успешно.
Пересборка проекта
Следующий шаг — автоматическая сборка проекта после переключения ветки:
console.log('Запуск пересборки...');
exec('npm run build', (buildError, stdout, stderr) => { // Запуск сборки проекта
if (buildError) {
console.error(`Ошибка сборки: ${buildError.message}`); // Обработка ошибки сборки
return;
}
console.log('Проект успешно собран.');
});
});
});
После успешного переключения ветки программа:
1. Выводит сообщение о том, что начинается пересборка.
2. Запускает команду npm run build
, которая выполняет сборку проекта.
3. Если сборка прошла успешно, выводится сообщение об успехе. В противном случае, если сборка не удалась, например, из-за отсутствующих зависимостей или ошибок в коде, выводится сообщение об ошибке.
Таким образом, вся рутинная работа — от переключения ветки до сборки — выполняется одной командой.
Проверка зависимостей (дополнительно)
Один из наиболее частых источников ошибок во время сборки — это несовместимые или отсутствующие зависимости. Поэтому я добавил возможность автоматической проверки зависимостей перед сборкой:
exec('npm install', (installError) => {
if (installError) {
console.error(`Ошибка установки зависимостей: ${installError.message}`);
return;
}
console.log('Все зависимости успешно установлены.');
exec('npm run build', (buildError) => {
if (buildError) {
console.error(`Ошибка сборки: ${buildError.message}`);
return;
}
console.log('Проект успешно собран.');
});
});
Теперь команда:
1. Выполняет npm install
, чтобы убедиться, что все зависимости установлены и обновлены.
2. Если установка зависимостей прошла успешно, запускает сборку проекта.
Это гарантирует, что каждый раз перед сборкой разработчик работает с актуальными версиями зависимостей, что предотвращает возможные конфликты и ошибки на этапе сборки.
4. Тестирование и доработка
После того как базовые команды были реализованы, я протестировал CLI на нескольких проектах. Конечно, по ходу тестирования возникли ошибки и недочёты, которые пришлось оперативно устранять. Например, иногда сборка зависала из-за конфликтов в зависимостях, и мне пришлось реализовать обработку таких ситуаций.
Я также добавил команду для автоматической установки нужных версий зависимостей для разных окружений. Это существенно упростило работу при переключении между проектами.
Заключение
Создание собственной CLI-интерфейса — это отличный способ не только автоматизировать повторяющиеся задачи, но и повысить продуктивность команды. Да, на разработку такого инструмента ушло некоторое время, но итоговый результат стоил того. Теперь наша команда может быстрее сосредотачиваться на важнейших задачах, а не тратить время на рутину.
CLI стала одним из ключевых элементов нашего рабочего процесса, и я рекомендую всем, кто сталкивается с регулярными рутинными задачами, задуматься о создании своего решения.
Комментарии: