かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Gulp node.js 実行時に変数を渡して処理を分岐させたい

以前 Gulpでタスクを指定して実行することで無理やり処理を分岐させる方法を書いていました。

今回同じような需要が合って調べているとgulp実行時コマンドに直接キーと引数を渡せる素晴らしい方法があったのでメモ。

minimistを使ってコマンドラインから変数を渡す

minimistというコマンドラインの引数をパースできるモジュールがあるようです。

var parseArgs = require('minimist')
var argv = parseArgs(args, opts={})

EX: コマンドラインの引数

// example.js
const options = require('minimist')(process.argv.slice(2));
console.log(options);

例えば上記のようなjsがあり、コンソールから次のようにコマンドを実行してみます。

$ node example.js do -v -x 3 -y=4 -z5 -ab -cd hoge -n6m10 -rx78v2 --env develop --beep=beep foo bar baz

👇パース結果

{ _: [ 'do', 'foo', 'bar', 'baz' ],
  v: true,
  x: 3,
  y: 4,
  z: 5,
  a: true,
  b: true,
  c: true,
  d: 'hoge',
  n: '6m10',
  r: 'x78v2',
  env: 'develop',
  beep: 'beep' }

- の挙動が少し複雑ですが、ざっくりこんな感じかなと思います。

  • - で始まる引数: 1文字のキーになり、キーの後ろにスペースまたは=を置いて値があれば、そのキーの値になる。値が無ければtrue
    キーが2文字以上になっている場合
    • 2文字目以降に数字が含まれる場合 => 2文字目以降がキーの値になる
    • 2文字目以降が文字列のみの場合 => 1文字づづキーに分解され、その後にスペースが有り値があれば、最後の文字にその値が設定される
  • -- で始まる引数: 文字列がキーになり、キーの後ろにスペースまたは=を置いて値があれば、キーに値が設定される。値が無ければtrue
  • それ以外の値は、_をキーにした配列の値になる。

 
キーが重複した場合は、-でも--でも明示的に値をtrueとしていない場合は置き換えられ、それ以外は値が配列になるようです

$ node example.js -s -n true -m -l -x 3 -y 4 -s false -n false -x 10 -y foo -m null -l undefined

👇

{ _: [],
  s: 'false',
  n: [ 'true', 'false' ],
  m: 'null',
  l: 'undefined',
  x: [ 3, 10 ],
  y: [ 4, 'foo' ] }

 

$ node example.js --flg --foo true --bar true --baz true --arg --flg false --foo false --bar null --baz undefined --arg false --arg null --arg undefined

👇

{ _: [],
  flg: 'false',
  foo: [ 'true', 'false' ],
  bar: [ 'true', 'null' ],
  baz: [ 'true', 'undefined' ],
  arg: [ 'false', 'null', 'undefined' ] }

オプションのデフォルト値を作成できる

minimistの第二引数に配列(オブジェクト)を与えると、コマンドラインから渡された引数の配列でマージすることができます。
コマンドラインで引数が指定されていない場合のデフォルト値を作ったりするのに便利です。

// gulpfile.js
const defaultOption = {
  // コマンドから渡される値のデフォルト値は default キーの中に設定する
  default: {
    env: 'develop',
    dir: 'root'
  }
}
const options = require('minimist')(process.argv.slice(2), defaultOption);
console.log(options);

// gulp task
gulp.task('compile', function() {
  console.log('do compile!');
});

コマンド

$ gulp compile --dir dev/test

👇

{ _: [ 'compile' ], dir: 'dev/test', env: 'develop' }
[21:32:45] Using gulpfile ~/Documents/local/example/gulpfile.js
[21:32:45] Starting 'compile'...
do compile!

gulpでもコマンドでタスクを指定して引数を渡すことも問題なくできました!

後はgulpfile.jsの中で、飛鳥に応じて取得されたオプションで対象のディレクトリを切り替えるとか、gulp-ifモジュールをつかってgulp.pipe内で処理を変更するとかすればイイ感じになりそうです。
minimist モジュール結構昔からあったみたいなので、今まで検索して見つけることができなかった事が悔やまれます...


[参考]

「宇宙よりと遠い場所」ってアニメすごく良かった。