LoginSignup
6
2

More than 5 years have passed since last update.

minimistはオプション値に数字を含むと挙動が変わるので注意

Posted at

Node.jsのコマンドラインツールを今作っているんですが、
引数のオプション処理に、minimistというライブラリを使ってます。

例えばこんなプログラムを書くと、

args.js
const argv = require('minimist')(process.argv.slice(2), {
  alias: {
    u: 'username',
  }
})

console.log('username: ', argv.username)

以下の5通りの実行方法で、どれも同じ結果を出してくれます。
便利ですねー。

$ node args.js -uUser1
$ node args.js -u User1
$ node args.js -u=User1
$ node args.js --username User1
$ node args.js --username=User1
username:  User1

しかし、 1文字オプション かつ オプション後にスペースを空けない 場合、
渡す文字列によっては失敗する場合があるのです。

例えばこちら、意図しない挙動になります。

$ node args.js -uAdmin
username:  true

試しにargv配列全体も出力してみましょう。

args.js
const argv = require('minimist')(process.argv.slice(2), {
  alias: {
    u: 'username',
  }
})

console.log(argv)
console.log('username: ', argv.username)
$ node args.js -uAdmin
{ _: [],
  u: true,
  username: true,
  A: true,
  d: true,
  m: true,
  i: true,
  n: true }
username:  true

わかりますね?以下の2つは同じ意味になっちゃうのです。

$ node args.js -uAdmin
$ node args.js -u -A -d -m -i -n
username:  true

ではなぜ最初の例ではうまくいったかというと、
オプションに渡す文字列に数字が含まれていたからです。

$ node args.js -uUser1
{ _: [], u: 'User1', username: 'User1' }
username:  User1

「オプションが数字1文字」はあり得ないので、
2文字目以降に数字が含まれる場合に限り、オプション値と見なすようですね。

軽くハマったので、メモでした〜。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2