Jak zatrzymać aplikację, która node.js wyraża „npm start”

100

Budujesz aplikację node.js za pomocą Express v4.x, a następnie uruchamiasz ją przez npm start . Moje pytanie brzmi: jak zatrzymać aplikację? Czy jest przystanek npm ?

EDYTUJ, aby uwzględnić błąd podczas implementowania zatrzymania npm

/home/nodetest2# npm stop

> nodetest2@0.0.1 stop /home/nodetest2
> pkill -s SIGINT nodetest2

pkill: invalid argument for option 's' -- SIGINT

npm ERR! nodetest2@0.0.1 stop: `pkill -s SIGINT nodetest2`
npm ERR! Exit status 2
ngungo
źródło

Odpowiedzi:

66

Tak, npm zapewnia również skrypt zatrzymujący:

npm help npm-scripts

prestop, stop, poststop: uruchamiane przez polecenie npm stop.

Ustaw jedno z powyższych w pliku package.json, a następnie użyj npm stop

npm help npm-stop

Można zrobić to naprawdę proste, jeśli się w app.js,

process.title = myApp;

Następnie w scripts.json

"scripts": {
    "start": "app.js"
    , "stop": "pkill --signal SIGINT myApp"
}

To powiedziawszy, gdyby to był ja, użyłbym pm2czegoś, co automatycznie załatwiło to na podstawie git push.

Evan Carroll
źródło
Nadal występuje błąd. Oczywiście jestem dobrze zorientowany w poleceniach liniowych.
ngungo
@ngungo raczej --signal. Użyj, man pkillaby przeczytać o pkill.
Evan Carroll
3
@EvanCarroll Co się stanie, jeśli uruchomionych jest wiele wystąpień aplikacji?
Amit Kumar Gupta
1
Każdy pomysł, jak to zaimplementować w aplikacji Angular 4. W szczególności gdzie mam ustawić tytuł procesu?
kiranghule27
40

Wszystkie inne rozwiązania są zależne od systemu operacyjnego. Niezależne rozwiązanie dla dowolnego systemu operacyjnego używa socket.io w następujący sposób.

package.json ma dwa skrypty:

"scripts": {
  "start": "node server.js",
  "stop": "node server.stop.js"
}

server.js - tutaj znajdują się Twoje zwykłe pliki ekspresowe

const express = require('express');
const app = express();
const server = http.createServer(app);
server.listen(80, () => {
  console.log('HTTP server listening on port 80');
});

// Now for the socket.io stuff - NOTE THIS IS A RESTFUL HTTP SERVER
// We are only using socket.io here to respond to the npmStop signal
// To support IPC (Inter Process Communication) AKA RPC (Remote P.C.)

const io = require('socket.io')(server);
io.on('connection', (socketServer) => {
  socketServer.on('npmStop', () => {
    process.exit(0);
  });
});

server.stop.js

const io = require('socket.io-client');
const socketClient = io.connect('http://localhost'); // Specify port if your express server is not using default port 80

socketClient.on('connect', () => {
  socketClient.emit('npmStop');
  setTimeout(() => {
    process.exit(0);
  }, 1000);
});

Wypróbuj to

npm start (aby uruchomić serwer jak zwykle)

npm stop (spowoduje to teraz zatrzymanie działającego serwera)

Powyższy kod nie został przetestowany (jest to okrojona wersja mojego kodu, mój kod działa), ale mam nadzieję, że działa tak, jak jest. Tak czy inaczej, zapewnia ogólny kierunek, jeśli chcesz użyć socket.io do zatrzymania serwera.

danday74
źródło
2
Piękno tego podejścia polega na tym, że w zasadzie można to uruchomić w dowolnym środowisku env, w tym w kontenerach, które zwykle są dość ograniczone do sposobu manipulowania procesami. Z mojej osobistej perspektywy - to najbardziej eleganckie podejście.
Der Zinger
16

Kiedy wypróbowałem sugerowane rozwiązanie, zauważyłem, że nazwa mojej aplikacji została obcięta. Przeczytałem process.titlew dokumentacji nodejs ( https://nodejs.org/docs/latest/api/process.html#process_process_title ) i jest tam napisane

W systemie Linux i OS X jest on ograniczony do rozmiaru nazwy binarnej oraz długości argumentów wiersza poleceń, ponieważ zastępuje pamięć argv.

Moja aplikacja nie używa żadnych argumentów, więc mogę dodać ten wiersz kodu do pliku app.js

process.title = process.argv[2];

a następnie dodaj te kilka wierszy do mojego package.jsonpliku

  "scripts": {
    "start": "node app.js this-name-can-be-as-long-as-it-needs-to-be",
    "stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be"
  },

używać naprawdę długich nazw procesów. npm starti npm stoppraca, oczywiście npm stop, zawsze kończą wszystkie uruchomione procesy, ale to jest w porządku dla mnie.


źródło
12

To jest problem z wersją miętową. Alternatywnie użyj cmd. Aby zabić proces serwera, po prostu uruchom to polecenie:

    taskkill -F -IM node.exe
Karan
źródło
2
nie jest dobrym pomysłem zabicie głównego node.exe, ponieważ spowoduje to problem w przypadku, gdy masz uruchomionych wiele aplikacji węzłów
user889030
11

W systemie MAC OS X (/ BSD): możesz spróbować użyć polecenia lsof (lista otwartych plików)

$ sudo lsof -nPi -sTCP:LISTEN

wprowadź opis obrazu tutaj

a więc

$ kill -9 3320
zwycięzca
źródło
9

Sprawdź wszystkie procesy za pomocą polecenia netstat -nptl

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      1736/mongod     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1594/sshd       
tcp6       0      0 :::3977                 :::*                    LISTEN      6231/nodejs     
tcp6       0      0 :::22                   :::*                    LISTEN      1594/sshd       
tcp6       0      0 :::3200                 :::*                    LISTEN      5535/nodejs 

I po prostu zabija proces przez odniesienie PID ... W moim przypadku chcę zatrzymać 6231 / nodejs, więc wykonuję następujące polecenie:

kill -9 6231
Samuel Ivan
źródło
1
Myślę, że OP szuka opcji skryptu NPM, a nie konsoli.
Faraji Anderson
4

Oto inne rozwiązanie, które łączy pomysły z poprzednich odpowiedzi. Przyjmuje podejście „procesu zabijania”, rozwiązując jednocześnie obawy dotyczące niezależności platformy.

Opiera się na drzewo-kill pakietu do obsługi zabijając drzewo procesów serwera. Zauważyłem, że zabijanie całego drzewa procesów jest konieczne w moich projektach, ponieważ niektóre narzędzia (np. babel-node) Uruchamiają procesy potomne. Jeśli chcesz zabić tylko jeden proces, możesz zastąpić zabijanie drzewa process.kill()metodą wbudowaną .

Rozwiązanie jest następujące (pierwsze dwa argumenty spawn()należy zmodyfikować, aby odzwierciedlić konkretną receptę na uruchomienie serwera):

build / start-server.js

import { spawn } from 'child_process'
import fs from 'fs'

const child = spawn('node', [
  'dist/server.js'
], {
  detached: true,
  stdio: 'ignore'
})
child.unref()

if (typeof child.pid !== 'undefined') {
  fs.writeFileSync('.server.pid', child.pid, {
    encoding: 'utf8'
  })
}

build / stop-server.js

import fs from 'fs'
import kill from 'tree-kill'

const serverPid = fs.readFileSync('.server.pid', {
  encoding: 'utf8'
})
fs.unlinkSync('.server.pid')

kill(serverPid)

package.json

"scripts": {
  "start": "babel-node build/start-server.js",
  "stop": "babel-node build/stop-server.js"
}

Zauważ, że to rozwiązanie odłącza skrypt startowy od serwera (tzn. npm startZwróci natychmiast i nie zablokuje się, dopóki serwer nie zostanie zatrzymany). Jeśli wolisz tradycyjne zachowanie blokujące, po prostu usuń options.detachedargument do spawn()i wywołanie do child.unref().

Rusty Shackleford
źródło
3

Jeśli już próbowałeś ctrl + ci nadal nie działa, możesz spróbować tego. To zadziałało dla mnie.

  1. Uruchom wiersz poleceń jako administrator. Następnie uruchom poniższe polecenie, aby znaleźć identyfikator procesu (PID), który chcesz zabić. Wpisz swój numer portu<yourPortNumber>

    netstat -ano | findstr :<yourPortNumber>

wprowadź opis obrazu tutaj

  1. Następnie wykonujesz to polecenie po zidentyfikowaniu PID.

    taskkill /PID <typeYourPIDhere> /F

wprowadź opis obrazu tutaj

Uznanie za @mit $ ingh z http://www.callstack.in/tech/blog/windows-kill-process-by-port-number-157

Jamezuh
źródło
2

Jeśli jest to bardzo proste, po prostu zakończ proces.

localmacpro$ ps
  PID TTY           TIME CMD
 5014 ttys000    0:00.05 -bash
 6906 ttys000    0:00.29 npm   
 6907 ttys000    0:06.39 node /Users/roger_macpro/my-project/node_modules/.bin/webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
 6706 ttys001    0:00.05 -bash
 7157 ttys002    0:00.29 -bash

localmacpro$ kill -9 6907 6906
rogersfo
źródło
1

W przypadku komputera z systemem Windows (jestem w systemie Windows 10), jeśli CTRL + C (Anuluj / Przerwij) Polecenie na cli nie działa, a ekran wygląda następująco:

wprowadź opis obrazu tutaj

Spróbuj najpierw nacisnąć ENTER (lub dowolny klawisz by to zrobił), a następnie CTRL + C, a bieżący proces zapyta, czy chcesz zakończyć zadanie wsadowe:

wprowadź opis obrazu tutaj

Być może CTRL + C kończy tylko proces nadrzędny, podczas gdy npm start działa z innymi procesami podrzędnymi. Całkiem nie jestem pewien, dlaczego musisz wcisnąć ten dodatkowy klawisz przed CTRL + C, ale działa to lepiej niż konieczność zamykania wiersza poleceń i rozpoczynania od nowa.

Powiązany problem, który możesz chcieć sprawdzić: https://github.com/mysticatea/npm-run-all/issues/74

Vincent Edward Gedaria Binua
źródło
0

W środowiskach produkcyjnych powinieneś używać Forever.js

Jest tak używany do uruchamiania i zatrzymywania procesu węzła, możesz też wyświetlić listę uruchomionych aplikacji.

https://github.com/foreverjs/forever

Carlos Jesus Arancibia Taborga
źródło
0

W przypadku, gdy twój plik json nie zawiera skryptu do zatrzymania aplikacji, opcją, której używam, jest po prostu naciśnięcie ctrl + C na cmd.

Felipe
źródło
-1

Wszystkie (3) rozwiązania to:

1- ctlr + C

2 - w pliku json utworzy skrypt, który się zatrzyma

"skrypty": {"stop": "killall -SIGINT this-name-can-be-as-long-as-it-need-to-be"},

* niż w poleceniu napisz // npm stop //

3- Uruchom ponownie komputer

Omar bakhsh
źródło
7
Zrestartuj komputer , naprawdę?!? Dlaczego po prostu nie przełączyć głównego wyłącznika? : D
stk
-2

Musisz nacisnąć kombinację ctrl + z Mój system operacyjny to Ubuntu

Тимур Сафаров
źródło