【Node.js】Yeomanのカスタムジェネレータを使って綺麗にログ出力

2pt   2018-10-11 13:30
IT技術情報局

はじめに

Yeomanのジェネレータとして、Goqoo on kintoneというScaffoldツールを作っております。

yeoman-generator内でthis.fs.copyTpl()とかでファイルをコピーすると、
Railsのジェネレータと同様、こんなカラフルなログを出してくれるのがとても良いですよね。
68747470733a2f2f71696974612d696d6167652d

こんなログを、自分の好きなタイミングで自由自在に出したいという話。

用途

this.spawnCommandSync()で子プロセスを走らせた時に、Railsのrun git init run bundle installみたいなログを出したかったんです。(Yeomanの標準機能で欲しいところですけどね)
68747470733a2f2f71696974612d696d6167652d

あとは、エラーメッセージもカラフルに出したいとか、色々あります。

やり方

基本:this.log配下の関数を使い分ける

ジェネレータ内でログ出力するときはthis.log()を使うことが多いと思いますが、実はその配下に、this.log.xxx()という関数がステータス別に沢山用意されています。

generators/app/index.js const Generator = require('yeoman-generator') module.exports = class extends Generator { configuring() { const str = 'Yo! ora goqoo!' this.log(str) this.log.write(str) this.log.writeln(str) this.log.ok(str) this.log.error(str) this.log.skip(str) this.log.force(str) this.log.create(str) this.log.invoke(str) this.log.conflict(str) this.log.identical(str) this.log.info(str) // ...do something } }

結果はこんな感じ。綺麗ですね!
デフォルトで用意されてるステータスで事足りるなら、これで十分です。
68747470733a2f2f71696974612d696d6167652d

ちなみに公式ドキュメントの解説はこの一言だけ!
「ソース読め!」としか書いてないスパルタ感 1f602.png?resize=20%2C20&ssl=1

Adapter#log()
It’s both a function and an object intended for generic output. See lib/util/log.js for the complete list of methods to provide.

応用:this.logにステータスを追加

最初に書いたrunというステータスは、残念ながら用意されていません。
しかし!カスタムステータスを定義する方法があります。

https://github.com/yeoman/environment/blob/v2.3.3/lib/util/log.js#L46-L51
この関数で生成されるのがthis.logの正体ですが、引数に以下のようなオブジェクトを渡して呼び出せばステータス&カラーを追加できるんですね。

{ colors: { status: color, } }

これをrequire('yeoman-environment/lib/util/log')とすることで、単独で使うことができます!

generators/app/index.js const Generator = require('yeoman-generator') const EnvironmentLogger = require('yeoman-environment/lib/util/log') module.exports = class extends Generator { constructor(args, options) { // 親コンストラクタを実行 super(args, options) // カスタムステータス付きのlogオブジェクトを作ってオーバーライド this.log = EnvironmentLogger({ colors: { run: 'green', }, }) } configuring() { this.log.skip('package.json') this.log.conflict('.eslintrc.yml') this.log.identical('.gitignore') this.log.run('git init') // ...do something } }

もちろん、デフォルトのステータスも引き続き使うことができます。こんな感じ〜♪
68747470733a2f2f71696974612d696d6167652d

Yeoman以外のNode.jsアプリで使う

普通のNodeアプリ内で、このloggerを単独で使うことも可能です。
こんな風にカジュアルに使っちゃうのも良いかもしれませんねっ!

const log = require('yeoman-environment/lib/util/log')() log.ok('完了です!') log.error('エラーです!')

68747470733a2f2f71696974612d696d6167652d

ちなみにRailsの場合

調べていくうちにどんどん興味が深くなり、Railsの調査にまで手を出してしまいましたw

rails newでrun bundle installみたいに出力してるのは、ここですね。
https://github.com/rails/rails/blob/v5.2.1/railties/lib/rails/generators/app_base.rb#L404

say_statusという関数で綺麗に出力できるようで、他にも至る所で使われています。
その定義はThorというライブラリ内にありました。色を指定しない場合はgreenになるようですね!
https://github.com/erikhuda/thor/blob/v0.20.0/lib/thor/shell/basic.rb#L101-L114

おわりに

この仕組みに辿り着くまでかなり苦労しました。。
日本語はおろか、英語の解説記事も全然なく、コードだけが頼りでした。

使い方さえ分かってしまえば至ってシンプルなので、Node.jsアプリでログを綺麗に、かつ苦労せず出したい皆さん、どんどん使ってみてくださいませ!

Source: rails tag

   ITアンテナトップページへ
情報処理/ITの話題が沢山。