process.argv è un array che contiene la riga di comando che ha avviato il tuo programma Node.js. L'indice 0 è il percorso dell'eseguibile node, l'indice 1 è il percorso del tuo script, e i tuoi argomenti iniziano dall'indice 2. Quindi process.argv.slice(2) ti dà esattamente quello che l'utente ha scritto dopo il nome del file, sempre come stringhe.
Le prime due voci sono percorsi completi, quindi stampa solo la loro ultima parte (node e index.js), poi [ 'Ada', '42', '--verbose' ]. Cambia la riga degli argomenti in Grace 7 ed eseguilo di nuovo: l'array cambia di conseguenza.
Cosa finisce in process.argv
La shell divide la riga dopo node sugli spazi e passa i pezzi a Node.js. I flag scritti prima del nome del file appartengono a Node.js stesso, non al tuo programma:
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' ]
Le virgolette raggruppano più parole in un solo argomento ("Ada Lovelace" arriva come una sola stringa), e la shell espande pattern come *.txt in nomi di file prima che Node.js li veda.
Leggere gli argomenti con slice(2)
La maggior parte degli script destruttura gli argomenti che si aspetta e dà a ciascuno un default:
Ha stampato Hello, Ada: un argomento ha riempito name, e greeting è tornato al suo default. Aggiungi Hi dopo Ada nella riga degli argomenti e stampa Hi, Ada; svuota la riga e ottieni Hello, world.
I numeri arrivano come stringhe
La shell non ha tipi. Ogni argomento è una stringa, quindi i calcoli vengono sbagliati finché non converti:
a + b ha unito le stringhe in 75, e Number() ha dato 12. Una parola che non è un numero diventa NaN, quindi controlla con Number.isNaN e stampa un messaggio d'uso invece di andare avanti con un valore rotto.
Parsing a mano dei flag --name=value
Per un paio di flag basta un breve ciclo. Questo trasforma --port=8080 in port: '8080', un --verbose da solo in true, e tiene tutto il resto come argomento posizionale:
Ha stampato {"port":"8080","verbose":true} e [ 'build', 'src' ], con port ancora come stringa. Questo ciclo non gestisce i flag brevi come -p né un valore nell'argomento successivo (--port 8080); per quello usa il parser integrato qui sotto.
util.parseArgs, il parser integrato
Node.js 18.3 e successivi includono util.parseArgs, che gestisce flag lunghi e brevi, valori nell'argomento successivo, booleani e default:
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 legge process.argv.slice(2) di default. Lancia un errore su un'opzione che non hai dichiarato, così intercetta errori di battitura come --prot; passa strict: false per accettare flag sconosciuti. I tipi delle opzioni sono solo string e boolean, quindi per i numeri serve ancora Number(). values è un oggetto senza prototype, ed è per questo che viene stampato con [Object: null prototype]; leggilo come qualsiasi oggetto.
Errori comuni
Leggere process.argv[0] come primo argomento. È il percorso di node. Il tuo primo argomento è process.argv[2].
Dimenticare che tutto è una stringa. '10' > '9' è false, perché le stringhe si confrontano carattere per carattere. Converti prima.
Mettere segreti negli argomenti. Le righe di comando finiscono nella cronologia della shell e negli elenchi dei processi che gli altri utenti della macchina possono leggere. Passa password e chiavi API tramite variabili d'ambiente.
Domande frequenti
Come passo argomenti a uno script npm?
Mettili dopo --: npm run start -- --port=4000. npm passa tutto quello che segue -- al tuo script, dove compare in process.argv.slice(2).
Perché process.argv[2] è undefined?
Perché il programma è stato avviato senza quell'argomento. Dagli un valore di default (process.argv[2] ?? 'guest'), oppure stampa una riga d'uso e fermati con process.exit(1).
Meglio usare yargs o commander invece di process.argv?
Per uno script con pochi flag, util.parseArgs è integrato e basta. Pacchetti come commander e yargs aggiungono testo di aiuto, sottocomandi e validazione, e valgono la pena quando il tuo tool ha diversi comandi.