Почему npm и yarn процесс остаётся после закрытия терминала
При запуске сборки фронтенда командами npm start, npm run dev или yarn dev Node.js запускает процесс, который слушает определённый порт (например, 3000, 4000, 8080). Если закрыть окно терминала без корректного завершения (Ctrl+C), процесс продолжает работать в фоновом режиме Windows и удерживает порт.
При следующей попытке запустить сборку появляется ошибка EADDRINUSE: address already in use — порт занят, и Node.js не может запустить новый сервер на том же порту. Решение — найти и завершить зависший процесс вручную.
Шаг 1: Найти PID процесса через netstat
Открываем командную строку (cmd.exe) и выполняем команду для поиска процесса по номеру порта. Рассмотрим на примере порта 4000.
Находим PID процесса:
|
1 |
netstat -ano | findstr :4000 |
В результате получим что-то вроде:
|
1 2 3 |
TCP 0.0.0.0:4000 0.0.0.0:0 LISTENING 2568 TCP [::]:4000 [::]:0 LISTENING 2568 TCP [::1]:4000 [::1]:59097 ESTABLISHED 2568 |
После слова LISTENING на необходимом порту идёт его PID. В нашем примере это 2568. Строки с ESTABLISHED — это активные соединения с тем же процессом.
Шаг 2: Завершить процесс через taskkill
Завершаем процесс с указанием PID (в нашем примере это 2568):
|
1 |
taskkill /PID 2568 /F |
Флаг /F означает принудительное завершение (force). Без него процесс может не завершиться, если он не реагирует на стандартный сигнал завершения. После выполнения команды вы увидите подтверждение: SUCCESS: The process with PID 2568 has been terminated.
Если на порту работает несколько процессов (разные PID), завершите каждый из них отдельно.
Альтернатива через PowerShell
PowerShell предоставляет более удобный способ работы с процессами. Откройте PowerShell от имени администратора и выполните:
|
1 2 3 4 5 6 7 8 9 10 11 |
# Найти процесс, занимающий порт 4000 Get-NetTCPConnection -LocalPort 4000 | Select-Object OwningProcess # Получить информацию о процессе по PID Get-Process -Id 2568 # Завершить процесс по PID Stop-Process -Id 2568 -Force # Или завершить все процессы node сразу Get-Process node | Stop-Process -Force |
Команда Get-NetTCPConnection доступна в PowerShell 4.0 и выше (Windows 8.1 / Server 2012 R2 и новее). Она удобнее netstat тем, что сразу возвращает PID без необходимости парсить текстовый вывод.
Альтернатива через Диспетчер задач
Если вы предпочитаете графический интерфейс, процесс можно завершить через Диспетчер задач (Task Manager):
- Откройте Диспетчер задач через Ctrl+Shift+Esc или правой кнопкой по панели задач.
- Перейдите на вкладку «Подробности» (Details).
- Найдите процесс
node.exeпо имени или по PID, который вы узнали через netstat. - Нажмите правой кнопкой и выберите «Завершить задачу» (End Task).
Как запустить сборку на другом порту
Иногда проще запустить процесс на другом свободном порту, чем завершать зависший. Большинство сборщиков поддерживают флаг --port:
|
1 2 3 4 5 6 7 8 |
# Для webpack-dev-server npm start -- --port 4001 # Для Vite npm run dev -- --port 4001 # Для Create React App через переменную среды (Windows cmd) set PORT=4001 && npm start |
Почему возникает ошибка EADDRINUSE: address already in use
Ошибка EADDRINUSE: address already in use :::4000 означает, что порт 4000 уже занят другим процессом в системе. Node.js не может привязаться к занятому адресу. Это происходит потому что:
- Предыдущий процесс сборки не был завершён корректно.
- На этом порту работает другое приложение (другой веб-сервер, база данных и т.д.).
- Операционная система ещё не освободила порт после недавнего завершения процесса (состояние TIME_WAIT).
Аналог команд на Linux и macOS
На Linux и macOS для решения той же задачи используются другие утилиты:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Найти процесс по порту lsof -i :4000 # Или через ss (современная замена netstat на Linux) ss -tulnp | grep 4000 # Завершить процесс по PID kill -9 2568 # Завершить все процессы node pkill -f node # Найти и сразу завершить процесс на порту одной командой kill -9 $(lsof -ti :4000) |
На Linux команды выполняются в обычном терминале без необходимости запускать от имени администратора (если только процесс не запущен от root).
Как автоматически освобождать порт при перезапуске
Чтобы не сталкиваться с этой проблемой регулярно, настройте скрипт в package.json, который сначала завершает старый процесс, а затем запускает новый. Для этого используется пакет kill-port:
|
1 |
npm install --save-dev kill-port |
Затем добавьте в секцию scripts файла package.json предварительное освобождение порта:
|
1 2 3 |
"scripts": { "start": "kill-port 4000 && node server.js" } |
Это позволяет запускать npm start без ошибок даже если предыдущая сессия не была завершена корректно. Пакет kill-port работает кроссплатформенно — одинаково на Windows, Linux и macOS.
