YAML/JSONでコマンド定義が書けるテンプレートジェネレータを作っている
この記事はNodeJS Adventcalendar 2016 の19日目の記事です。 もうクリスマスということで、大幅に遅れてしまって申し訳ございません。
色々とnodejsのCLIや、electronやwebなどを作っていく中で、僕の利用するスタックはだいたい同じなので、毎回package.jsonから書いていくのだるいなーというところから、YAML/JSONで定義ができる(Yet Another Yeoman的な)ツール作ろう、と思って書いて、それからずっと放置してました。 良い機会 & やる気を取り戻すためにもちょっと紹介します。
hiaというテンプレートジェネレータです。
Getting Started
hiaを利用して、簡単なジェネレータを作ってみました。 これはreact + flux-util + flowtypeのテンプレートを作ってくれます。
npm install -g @joe-re/hia-react-fluxutil
でinstallできます。
あとは以下のように適当なディレクトリを作り、hia-flux init
コマンドを叩いてみてください。
$ mkdir hia-flux-sample $ cd hia-flux-sample $ hia-flux init created src/components/Counter.jsx created src/actions/CounterAction.js created src/stores/CounterStore.js created src/containers/CounterContainer.jsx created src/routers/AppRouter.jsx created src/AppDispatcher.js created src/index.html created src/index.jsx created .flowconfig created .babelrc created webpack.config.js created package.json
ファイルが作成されたら、npm install
の後にnpm start
を叩くことで、アプリケーションが動きます。
YAML定義の例
実際にどんな感じのyamlを定義するのか、というとこんな感じです。
--- basedir: ./test command: hia subcommands: test:view: description: generate view template. input: true templates: src: fixtures/component.ejs script: fixtures/scripts/test.js output: dir: test/dist filename: '[name].jsx' args: feature_name: aliase: f description: Feature name. It is used as second directory name.(If you specify calendar, create 'test/dist/calendar/[name].jsx') require_args: aliase: r description: require args. required: true question_args: aliase: q description: This is Question Section. before: fixtures/scripts/before.js question: true default_args: aliase: d description: set default value. default: 'default value'
コマンド定義の説明
command: hia
でcommand名を定義しています。
subcommands: test:view:
みたいな感じでsubcommandを定義しています。つまりこれでhia test:view
コマンドが定義されました。
このコマンドはinput:true
を設定しているので、inputを受け付けます。
つまりhia test:view <INPUT>
という形式のコマンドとなります。
最後にargsセクションで以下のような定義をしています。
args: feature_name: aliase: f description: Feature name. It is used as second directory name.(If you specify calendar, create 'test/dist/calendar/[name].jsx') require_args: aliase: r description: require args. required: true question_args: aliase: q description: This is Question Section. before: fixtures/scripts/before.js question: true default_args: aliase: d description: set default value. default: 'default value'
これらはそれぞれ、CLIのオプションとして渡せます。 --feature_name hoge
ならfeature_nameというオプションでhogeとして受け取れます。ここで必須にしたいパラメータは required: true
で表現します。default valueの設定もできます。
ちなみにこれらの定義をしただけで、なんとなく良い感じのhelpが表示されるようにしています。
$ hia -h Easy and customizable generator system for creating template. Usage: hia <SUBCOMMAND> <INPUT> -h, --help Show list available subcommands and some concept guides. -c, --config specify config file path. Subcommands: hia component <INPUT> generate view template. -t, --text text on your component.
テンプレートのrenderの定義の説明
テンプレートはejsを解釈してrenderします。inputやargsセクションの定義で受け取った値は、そのままinputならinput、argsならそれぞれのオプション名が変数名になります。
templatesセクションには、{ src: 'ファイルパス', name: 'ファイル名の文字列' }
というオブジェクトの配列を設定できます。このsrcにejsのファイルパスを設定します。ここで設定したnameは、outputセクションで{ filename: '[name].js' }
と設定することで出力時の名前として使うことができます。
scriptセクションを設定することで、render直前にスクリプトを挟むこともできます。scriptは以下のように記述します。
module.exports = function script(params) { params.subcommand.output.dir += '/exchanged'; params.cliParams.input += 'Exchanged'; return params; };
paramsはsubcommandとcliParamsの2つのオブジェクトを持っています。 引数で受け取ったオブジェクトを、変更してreturnで返すことでrenderされる直前にパラメータを変更することが可能です。
subcommandはhia.yaml(json)で定義したコマンドの設定を含みます。上の例では出力先ディレクトリを変更しています。 cliParamsはinputやargsで受け取ったparameterを持っています。
所感
1人でやっている分には、初回設定が楽になるわー、ぐらいの感覚で使えているのだけど、大勢の人に使ってもらおうと思うと完全に雑な作りなので、もっと改良していきたい。具体的にはwiredep的な機能付けて、templateに追加でコードが書けるような仕組み欲しいなー、とか思っている。 やっていきを継続して行きたい。