ユーザーとのインタラクション

ジェネレーターはエンドユーザーと頻繁にインタラクションします。デフォルトでは、Yeoman はターミナル上で動作しますが、さまざまなツールが提供するカスタムユーザーインターフェースもサポートしています。たとえば、エディターやスタンドアロンアプリなどのグラフィカルツール内で Yeoman ジェネレーターを実行するのを妨げるものはありません。

この柔軟性を可能にするために、Yeoman は一連のユーザーインターフェース要素の抽象化を提供します。エンドユーザーとインタラクションする際には、これらの抽象化のみを使用する責任が作成者にはあります。他の方法を使用すると、ジェネレーターがさまざまな Yeoman ツールで正しく動作しなくなる可能性があります。

たとえば、コンテンツを出力するために console.log()process.stdout.write() を使用することは決して重要ではありません。これらを使用すると、ターミナルを使用していないユーザーからの出力が非表示になります。代わりに、常に UI ジェネリックな this.log() メソッドを使用してください。this は現在のジェネレーターのコンテキストです。

ユーザーインタラクション

プロンプト

プロンプトは、ジェネレーターがユーザーとインタラクションする主な方法です。プロンプトモジュールは Inquirer.js によって提供されており、使用可能なプロンプトオプションのリストについては そのAPIを参照 してください。

prompt メソッドは非同期であり、Promise を返します。次のタスクを実行する前に完了を待つには、タスクから Promise を返す必要があります。(非同期タスクの詳細はこちら)

module.exports = class extends Generator {
  async prompting() {
    const answers = await this.prompt([
      {
        type: "input",
        name: "name",
        message: "Your project name",
        default: this.appname // Default to current folder name
      },
      {
        type: "confirm",
        name: "cool",
        message: "Would you like to enable the Cool feature?"
      }
    ]);

    this.log("app name", answers.name);
    this.log("cool feature", answers.cool);
  }
};

ここで、ユーザーからのフィードバックを求めるために prompting キュー を使用することに注意してください。

後続段階でのユーザー回答の使用

非常に一般的なシナリオは、後続段階(例:writing キュー)でユーザーの回答を使用することです。これは、this コンテキストに追加することで簡単に実現できます。

module.exports = class extends Generator {
  async prompting() {
    this.answers = await this.prompt([
      {
        type: "confirm",
        name: "cool",
        message: "Would you like to enable the Cool feature?"
      }
    ]);
  }

  writing() {
    this.log("cool feature", this.answers.cool); // user answer `cool` used
  }
};

ユーザー設定の記憶

ユーザーは、ジェネレーターを実行するたびに、特定の質問に対して同じ入力を与える場合があります。これらの質問については、ユーザーが以前に回答した内容を記憶し、その回答を新しい default として使用することをお勧めします。

Yeoman は、質問オブジェクトに store プロパティを追加することで、Inquirer.js API を拡張します。このプロパティを使用すると、ユーザーが提供した回答を将来のデフォルト回答として使用することを指定できます。これは次のように行うことができます。

this.prompt({
  type: "input",
  name: "username",
  message: "What's your GitHub username",
  store: true
});

注記: デフォルト値を指定すると、ユーザーは空の回答を返すことができなくなります。

プロンプトに直接結び付けずにデータを保存するだけの場合、Yeoman ストレージのドキュメント を確認してください。

引数

引数はコマンドラインから直接渡されます。

yo webapp my-project

この例では、my-project が最初の引数になります。

引数を期待することをシステムに通知するには、this.argument() メソッドを使用します。このメソッドは name (文字列) とオプションのオプションのハッシュを受け取ります。

name 引数は、this.options[name] として使用できるようになります。

options ハッシュは複数のキーバリューペアを受け入れます。

  • desc 引数の説明
  • required 必須かどうかを示すブール値
  • type 文字列、数値、配列(生の文字列値を受け取って解析するカスタム関数にすることもできます)
  • default この引数のデフォルト値

このメソッドは constructor メソッド内で呼び出す必要があります。そうしないと、ユーザーがヘルプオプション付きでジェネレーターを呼び出した場合(例:yo webapp --help)、Yeoman は関連するヘルプ情報を出力できません。

例を以下に示します。

module.exports = class extends Generator {
  // note: arguments and options should be defined in the constructor.
  constructor(args, opts) {
    super(args, opts);

    // This makes `appname` a required argument.
    this.argument("appname", { type: String, required: true });

    // And you can then access it later; e.g.
    this.log(this.options.appname);
  }
};

Array 型の引数には、ジェネレーターに渡された残りのすべての引数が含まれます。

オプション

オプションは引数と非常によく似ていますが、コマンドラインの *フラグ* として記述されます。

yo webapp --coffee

オプションを期待することをシステムに通知するには、this.option() メソッドを使用します。このメソッドは name (文字列) とオプションのオプションのハッシュを受け取ります。

name の値は、対応するキー this.options[name] でオプションを取得するために使用されます。

options ハッシュ(第2引数)は複数のキーバリューペアを受け入れます。

  • desc オプションの説明
  • alias オプションの省略名
  • type ブール値、文字列、または数値(生の文字列値を受け取って解析するカスタム関数にすることもできます)
  • default デフォルト値
  • hide ヘルプから非表示にするかどうかを示すブール値

例を以下に示します。

module.exports = class extends Generator {
  // note: arguments and options should be defined in the constructor.
  constructor(args, opts) {
    super(args, opts);

    // This method adds support for a `--coffee` flag
    this.option("coffee");

    // And you can then access it later; e.g.
    this.scriptSuffix = this.options.coffee ? ".coffee" : ".js";
  }
};

情報の出力

情報の出力は this.log モジュールによって処理されます。

使用する主なメソッドは単に this.log です(例:this.log('Hey! Welcome to my awesome generator'))。これは文字列を受け取り、それをユーザーに出力します。基本的に、ターミナルセッション内で使用する場合、console.log() を模倣します。次のように使用できます。

module.exports = class extends Generator {
  myAction() {
    this.log("Something has gone wrong!");
  }
};

API ドキュメント には他にもいくつかのヘルパーメソッドがあります。