Slicing process.argv by hand works until the first user types -o build instead of --out=build. util.parseArgs, stable since Node 20.0.0, removes the usual reason to add commander or yargs to a small tool.
import { parseArgs } from 'node:util';
const { values, positionals } = parseArgs({
allowPositionals: true, allowNegative: true,
options: {
out: { type: 'string', short: 'o', default: 'dist' },
define: { type: 'string', short: 'D', multiple: true, default: [] },
minify: { type: 'boolean', default: true },
} });
console.log('values :', values);
console.log('positionals:', positionals);Output
$ node build.js -o build -D NODE_ENV=production -D API=/v1 --no-minify src/main.js src/admin.js
values : [Object: null prototype] {
out: 'build',
define: [ 'NODE_ENV=production', 'API=/v1' ],
minify: false
}
positionals: [ 'src/main.js', 'src/admin.js' ]multiple: true collects repeats into an array instead of letting the last one win; default fills in absent values, so nothing downstream tests for undefined; allowNegative turns --no-minify into minify: false, the only way to switch off an option that defaults to true; and strict, on by default, throws ERR_PARSE_ARGS_UNKNOWN_OPTION on a typo. values has a null prototype, so --__proto__ cannot poison anything.