Nodemon для JavaScript (Node.js): полное руководство с примерами
1. Что это и зачем нужна
Nodemon — это утилита для разработки на Node.js, которая автоматически перезапускает сервер (или любое другое Node.js-приложение) при обнаружении изменений в файлах проекта. Она является незаменимым инструментом для веб-разработчиков, работающих с Express, Koa, Fastify и другими фреймворками. Вместо того чтобы вручную останавливать и запускать сервер после каждого изменения кода, Nodemon делает это за вас, отслеживая файловую систему и реагируя на события сохранения файлов.
Основная задача Nodemon — ускорить цикл разработки. Без него разработчик тратит время на повторяющиеся действия: Ctrl+C, стрелка вверх, Enter. С Nodemon этот процесс полностью автоматизирован. Он не только перезапускает процесс, но и корректно обрабатывает завершение предыдущего экземпляра, освобождая порты и ресурсы. Кроме того, Nodemon умеет игнорировать определенные файлы и папки (например, node_modules или .git), что снижает нагрузку на процессор и дисковую подсистему.
Важно понимать, что Nodemon — это не библиотека в классическом смысле (как Lodash или Axios), а CLI-инструмент (Command Line Interface). Он не предназначен для импорта в код как модуль (хотя технически это возможно через API). Его основное использование — запуск из командной строки или через скрипты в package.json. Nodemon поддерживает все операционные системы (Windows, macOS, Linux) и работает с любой версией Node.js.
2. Установка
Nodemon устанавливается через npm (Node Package Manager). Рекомендуется устанавливать его глобально или как dev-зависимость в проекте.
Глобальная установка (для всех проектов):
npm install -g nodemon
Локальная установка (для конкретного проекта):
npm install --save-dev nodemon
После локальной установки вы можете запускать Nodemon через npx или добавив скрипт в package.json:
{
"scripts": {
"dev": "nodemon app.js"
}
}
Затем запуск: npm run dev.
3. Быстрый старт — минимальный рабочий пример
Создайте файл app.js с простым HTTP-сервером:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, World!\n');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
Теперь запустите Nodemon:
nodemon app.js
Вы увидите вывод:
[nodemon] 3.1.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node app.js`
Server running at http://localhost:3000/
Попробуйте изменить текст в res.end() на 'Hello, Nodemon!\n' и сохраните файл. Nodemon автоматически перезапустит сервер, и вы увидите обновленный ответ при обновлении страницы в браузере.
4. Основные методы/функции/классы
Nodemon предоставляет как CLI-интерфейс, так и программный API. Ниже приведены основные методы и возможности с примерами.
4.1. nodemon([options]) — Программный запуск
Сигнатура: nodemon([options: Object])
Что делает: Запускает Nodemon программно из Node.js-скрипта. Позволяет тонко настроить поведение и обрабатывать события.
Пример:
const nodemon = require('nodemon');
nodemon({
script: 'app.js',
ext: 'js json html',
ignore: ['node_modules/', 'test/'],
env: { NODE_ENV: 'development' }
});
nodemon.on('start', () => {
console.log('Nodemon запущен!');
});
nodemon.on('restart', (files) => {
console.log('Файлы изменены:', files);
});
nodemon.on('quit', () => {
console.log('Nodemon остановлен');
process.exit();
});
4.2. nodemon.on(event, callback) — Обработка событий
Сигнатура: nodemon.on(event: string, callback: Function)
Что делает: Позволяет подписаться на события жизненного цикла Nodemon: start, restart, quit, crash, log.
Пример:
const nodemon = require('nodemon');
nodemon({ script: 'server.js' });
nodemon.on('crash', () => {
console.error('Приложение упало с ошибкой!');
// Можно перезапустить вручную
nodemon.restart();
});
nodemon.on('log', (msg) => {
console.log('Лог:', msg.colour);
});
4.3. nodemon.restart() — Принудительный перезапуск
Сигнатура: nodemon.restart()
Что делает: Принудительно перезапускает отслеживаемый процесс. Полезно, когда нужно перезагрузить сервер по внешнему сигналу или после выполнения каких-либо задач.
Пример:
const nodemon = require('nodemon');
nodemon({ script: 'worker.js' });
// Перезапуск каждые 10 минут
setInterval(() => {
console.log('Плановый перезапуск...');
nodemon.restart();
}, 600000);
4.4. nodemon.reset() — Сброс состояния
Сигнатура: nodemon.reset()
Что делает: Сбрасывает внутреннее состояние Nodemon (список отслеживаемых файлов, таймеры). Используется редко, в основном для тестирования.
Пример:
const nodemon = require('nodemon');
nodemon({ script: 'app.js' });
// После каких-то манипуляций сбросить состояние
setTimeout(() => {
nodemon.reset();
nodemon.emit('quit');
}, 5000);
4.5. nodemon.config — Объект конфигурации
Сигнатура: nodemon.config (свойство)
Что делает: Предоставляет доступ к текущей конфигурации Nodemon. Позволяет читать или изменять настройки во время выполнения.
Пример:
const nodemon = require('nodemon');
nodemon({ script: 'server.js', ext: 'js' });
console.log('Текущий скрипт:', nodemon.config.script);
console.log('Отслеживаемые расширения:', nodemon.config.ext);
// Изменение расширений на лету
nodemon.config.ext = 'js json';
4.6. nodemon.emit(event, [...args]) — Эмуляция событий
Сигнатура: nodemon.emit(event: string, ...args: any[])
Что делает: Позволяет вручную эмулировать события Nodemon. Полезно для тестирования или отладки.
Пример:
const nodemon = require('nodemon');
nodemon({ script: 'app.js' });
// Эмулируем событие перезапуска
nodemon.emit('restart', ['/path/to/changed/file.js']);
// Эмулируем событие ошибки
nodemon.emit('crash', new Error('Test error'));
4.7. --watch (CLI опция) — Отслеживание конкретных путей
Сигнатура: nodemon --watch <path> [--watch <path2>] script.js
Что делает: Указывает Nodemon отслеживать только определенные директории или файлы. Уменьшает нагрузку и предотвращает лишние перезапуски.
Пример:
nodemon --watch src --watch config server.js
В этом примере Nodemon будет отслеживать изменения только в папках src и config, игнорируя все остальные.
4.8. --ignore (CLI опция) — Игнорирование путей
Сигнатура: nodemon --ignore <pattern> [--ignore <pattern2>] script.js
Что делает: Позволяет явно указать файлы или директории, которые не должны вызывать перезапуск. Полезно для логов, временных файлов, скомпилированного кода.
Пример:
nodemon --ignore 'dist/*' --ignore 'logs/*' app.js
4.9. --delay (CLI опция) — Задержка перезапуска
Сигнатура: nodemon --delay <time> script.js
Что делает: Добавляет задержку перед перезапуском после обнаружения изменений. Полезно, когда файлы сохраняются пачками (например, при использовании Webpack или TypeScript).
Пример:
nodemon --delay 2.5 server.js
Задержка в 2.5 секунды перед перезапуском.
4.10. --exec (CLI опция) — Замена команды запуска
Сигнатура: nodemon --exec <command> script.js
Что делает: Позволяет заменить стандартную команду node на другую, например, для запуска TypeScript (ts-node), Python, или любого другого интерпретатора.
Пример:
nodemon --exec "ts-node" app.ts
nodemon --exec "python3" app.py
nodemon --exec "babel-node" app.js
5. Реальный практический пример (100-200 строк кода)
Создадим полноценное Express-приложение с Nodemon для разработки. Структура проекта:
my-app/
├── src/
│ ├── index.js
│ ├── routes/
│ │ └── api.js
│ └── utils/
│ └── logger.js
├── public/
│ └── index.html
├── package.json
└── nodemon.json
package.json:
{
"name": "my-app",
"version": "1.0.0",
"description": "Пример приложения с Nodemon",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon --config nodemon.json",
"dev:debug": "nodemon --inspect src/index.js"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.1.0"
}
}
nodemon.json (конфигурация):
{
"watch": ["src/", "public/"],
"ignore": ["node_modules/", "test/"],
"ext": "js,json,html,css",
"delay": "1",
"env": {
"NODE_ENV": "development",
"PORT": "3000"
},
"events": {
"restart": "echo 'Сервер перезапущен!'"
}
}
src/index.js (главный файл):
const express = require('express');
const path = require('path');
const apiRouter = require('./routes/api');
const logger = require('./utils/logger');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(express.json());
app.use(express.static(path.join(__dirname, '..', 'public')));
// Логирование всех запросов
app.use((req, res, next) => {
logger.info(`${req.method} ${req.url}`);
next();
});
// Маршруты
app.use('/api', apiRouter);
// Главная страница
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '..', 'public', 'index.html'));
});
// Обработка ошибок
app.use((err, req, res, next) => {
logger.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});
// Запуск сервера
const server = app.listen(PORT, () => {
logger.info(`Сервер запущен на http://localhost:${PORT}`);
logger.info(`Окружение: ${process.env.NODE_ENV}`);
});
// Graceful shutdown
process.on('SIGTERM', () => {
logger.info('Получен сигнал SIGTERM, завершаем работу...');
server.close(() => {
process.exit(0);
});
});
module.exports = app;
src/routes/api.js:
const express = require('express');
const router = express.Router();
// Хранилище данных (в реальном проекте — база данных)
let items = Также в библиотеке
Elasticsearch клиент для Go (Golang): полное руководство по работе с ES
Парсинг HTML в Kotlin: jsoup, ktor, khtml и другие инструменты
Стандартная библиотека JavaScript (Node.js): полный обзор
Криптография в TypeScript: Обзор библиотеки crypto-js