Как настроить автоматическую перекомпиляцию Rust-проекта при изменении файлов?
Всем привет! Я новичок в Rust и использую Cargo для сборки проектов. Меня очень раздражает, что после каждого изменения в коде мне приходится вручную запускать cargo build или cargo run. Я привык к автоматической перекомпиляции в других языках (например, в Node.js с nodemon или в Python с --reload).
Вот мой типичный workflow:
// main.rs
fn main() {
println!("Hello, world!");
}
Я редактирую файл, сохраняю его, потом бегу в терминал и пишу cargo run. Это отнимает время и нарушает поток мыслей. Я слышал, что есть инструменты вроде cargo-watch, но не уверен, как их правильно установить и использовать.
Подскажите, пожалуйста, как настроить автоматическую перекомпиляцию и перезапуск программы при изменении исходных файлов? Хотелось бы получить решение, которое работает стабильно, не требует сложной настройки и подходит как для маленьких учебных проектов, так и для более серьёзных приложений.
Заранее спасибо за помощь!
<<Установка и использование cargo-watch
Самый популярный и надёжный способ автоматической перекомпиляции в Rust — это утилита cargo-watch. Она отслеживает изменения в файлах вашего проекта и автоматически запускает указанную команду Cargo.
Установка
Установите cargo-watch через Cargo (один раз):
cargo install cargo-watch
Базовое использование
Запустите в корневой папке вашего проекта:
cargo watch -x run
Теперь при каждом сохранении файла Cargo автоматически перекомпилирует и запустит вашу программу. Флаг -x означает "execute" (выполнить команду).
Продвинутые примеры
- Только компиляция без запуска:
cargo watch -x build - Запуск тестов при изменениях:
cargo watch -x test - Несколько команд последовательно:
cargo watch -x check -x test -x runСначала проверка (
check), потом тесты, потом запуск. - Игнорирование определённых файлов:
cargo watch -x run -i "target/*,*.log" - Задержка перед перезапуском (полезно при сохранении больших файлов):
cargo watch -x run --delay 2
Почему это работает?
cargo-watch использует системные утилиты для отслеживания файловой системы (inotify на Linux, FSEvents на macOS, ReadDirectoryChanges на Windows). Он реагирует на любые изменения в папке проекта, кроме указанных в игнорировании. Это гораздо эффективнее, чем постоянный опрос файловой системы.
Важные советы
- Не используйте cargo-watch в продакшене — это инструмент для разработки.
- Если программа зависает (например, ожидает ввода), cargo-watch не сможет перезапустить её автоматически. Используйте
Ctrl+Cдля остановки. - Для веб-приложений рассмотрите
systemfdиlistenfd(из крейтаlistenfd) для горячей перезагрузки без потери порта. - Альтернатива:
cargo watch -c -x run(флаг-cочищает экран перед каждым запуском).
Пример полного workflow
# Установка
cargo install cargo-watch
# Разработка
cd my_project
cargo watch -x run
# Теперь просто редактируйте код — всё перекомпилируется автоматически!
Это решение сэкономит вам часы времени и сделает разработку на Rust такой же плавной, как в динамических языках.
<<Использование cargo-watch с горячей перезагрузкой для веб-приложений
Если вы разрабатываете веб-сервер на Rust (например, с Actix-web, Rocket или Axum), просто cargo watch -x run может быть неудобен, так как при перезапуске теряется TCP-порт. Решение — использовать systemfd и listenfd.
Установка
cargo install systemfd cargo-watch
Настройка сервера
Добавьте в Cargo.toml:
[dependencies]
listenfd = "1.0"
Измените код сервера для использования переданного файлового дескриптора:
use listenfd::ListenFd;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut listenfd = ListenFd::from_env();
let server = HttpServer::new(|| App::new().route("/", web::get().to(|| HttpResponse::Ok())));
let server = if let Some(l) = listenfd.take_tcp_listener(0)? {
server.listen(l)?
} else {
server.bind("127.0.0.1:8080")?
};
server.run().await
}
Запуск
systemfd --no-pid -s http::8080 -- cargo watch -x run
Теперь при изменении файлов сервер перезапускается без потери порта и без прерывания соединений. Это особенно полезно при разработке API.
Ответов пока нет.
Войдите чтобы оставить ответ