Menu

process.argv w Node.js: argumenty wiersza poleceń

process.argv to tablica z wierszem poleceń, który uruchomił twój program: plik wykonywalny node, ścieżka skryptu, a potem każdy wpisany argument. process.argv.slice(2) daje tylko twoje argumenty.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

process.argv to tablica z wierszem poleceń, który uruchomił twój program Node.js. Indeks 0 to ścieżka do pliku wykonywalnego node, indeks 1 to ścieżka do twojego skryptu, a twoje własne argumenty zaczynają się od indeksu 2. Dlatego process.argv.slice(2) daje dokładnie to, co użytkownik wpisał po nazwie pliku, zawsze jako stringi.

Dwa pierwsze wpisy to pełne ścieżki, więc przykład wypisuje tylko ich ostatnią część (node i index.js), a potem [ 'Ada', '42', '--verbose' ]. Zmień wiersz argumentów na Grace 7 i uruchom ponownie: tablica się zmieni.

Co trafia do process.argv

Powłoka dzieli linię po node na spacjach i przekazuje kawałki do Node.js. Flagi zapisane przed nazwą pliku należą do samego Node.js, a nie do twojego programu:

node --max-old-space-size=4096 index.js --port=8080
# process.argv.slice(2) is [ '--port=8080' ]
# process.execArgv is      [ '--max-old-space-size=4096' ]

Cudzysłowy łączą słowa w jeden argument ("Ada Lovelace" przychodzi jako jeden string), a powłoka rozwija wzorce takie jak *.txt w nazwy plików, zanim Node.js je w ogóle zobaczy.

Pobieranie argumentów przez slice(2)

Większość skryptów destrukturyzuje oczekiwane argumenty i daje każdemu wartość domyślną:

Wypisało Hello, Ada: jeden argument wypełnił name, a greeting dostało wartość domyślną. Dopisz Hi po Ada w wierszu argumentów, a wypisze się Hi, Ada; wyczyść wiersz, a dostaniesz Hello, world.

Liczby przychodzą jako stringi

Powłoka nie zna typów. Każdy argument to string, więc arytmetyka na nich działa źle, dopóki ich nie zamienisz:

a + b skleiło stringi w 75, a Number() dało 12. Słowo, które nie jest liczbą, zmienia się w NaN, więc sprawdzaj przez Number.isNaN i wypisz instrukcję użycia, zamiast kontynuować z zepsutą wartością.

Ręczne parsowanie flag --name=value

Przy kilku flagach wystarczy krótka pętla. Ta zamienia --port=8080 na port: '8080', samo --verbose na true, a resztę zostawia jako argumenty pozycyjne:

Wypisało {"port":"8080","verbose":true} i [ 'build', 'src' ], a port jest nadal stringiem. Ta pętla nie obsługuje krótkich flag, np. -p, ani wartości w następnym argumencie (--port 8080); do tego użyj wbudowanego parsera poniżej.

util.parseArgs, wbudowany parser

Node.js 18.3 i nowsze mają util.parseArgs, które obsługuje długie i krótkie flagi, wartości w następnym argumencie, wartości logiczne i domyślne:

const { parseArgs } = require('node:util');

// node index.js -p 8080 --verbose src
const { values, positionals } = parseArgs({
    options: {
        port: { type: 'string', short: 'p', default: '3000' },
        verbose: { type: 'boolean', short: 'v' },
    },
    allowPositionals: true,
});

console.log(values);      // [Object: null prototype] { port: '8080', verbose: true }
console.log(positionals); // [ 'src' ]

parseArgs domyślnie czyta process.argv.slice(2). Rzuca wyjątek przy opcji, której nie zadeklarowałeś, co wyłapuje literówki takie jak --prot; przekaż strict: false, żeby akceptować nieznane flagi. Typy opcji to tylko string i boolean, więc liczby nadal wymagają Number(). values to obiekt bez prototypu i dlatego wypisuje się z [Object: null prototype]; czytaj go jak każdy obiekt.

Częste błędy

Traktowanie process.argv[0] jako pierwszego argumentu. To ścieżka do node. Twój pierwszy argument to process.argv[2].

Zapominanie, że wszystko jest stringiem. '10' > '9' to false, bo stringi porównuje się znak po znaku. Najpierw zamień na liczby.

Wpisywanie sekretów w argumenty. Wiersze poleceń trafiają do historii powłoki i list procesów, które mogą odczytać inni użytkownicy maszyny. Hasła i klucze API przekazuj przez zmienne środowiskowe.

Najczęściej zadawane pytania

Jak przekazać argumenty do skryptu npm?

Wpisz je po --: npm run start -- --port=4000. npm przekazuje wszystko po -- do twojego skryptu, gdzie pojawia się to w process.argv.slice(2).

Dlaczego process.argv[2] jest undefined?

Bo program uruchomiono bez tego argumentu. Daj mu wartość domyślną (process.argv[2] ?? 'guest') albo wypisz instrukcję użycia i zakończ przez process.exit(1).

Czy zamiast process.argv użyć yargs albo commander?

Dla skryptu z kilkoma flagami util.parseArgs jest wbudowane i wystarczy. Pakiety takie jak commander i yargs dodają tekst pomocy, podkomendy i walidację, co się opłaca, gdy narzędzie ma kilka komend.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

Zacznij