產生器將會頻繁地與最終使用者互動。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
佇列 向使用者索取意見回饋。
在後續階段使用使用者解答
一個非常常見的場景是在後續階段使用使用者解答,例如 寫入
佇列 中。這可以透過將它們新增至 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
}
};
記住使用者偏好設定
使用者可能會在每次執行產生器時,針對某些問題給出相同的輸入。對於這些問題,您可能會想要記住使用者之前回答的內容,並將該解答用作新的 預設值
。
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]
的形式提供。
選項雜湊接受多組關鍵字值對。
desc
引數說明required
布林值,指定是否為必要欄位type
字串、數字、陣列(也可以是接收原始字串值並進行剖析的自訂函式)default
此引數的預設值
必須在 constructor
方法內呼叫此方法。否則,當使用者使用說明選項呼叫產生器時,Yeoman 將無法輸出相關的說明資訊:例如 yo webapp --help
。
以下為一個範例
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
型別的引數將包含所有傳遞至產生器的剩餘引數。
選項
選項看起來很像引數,不過它們寫成指令列「flag」。
yo webapp --coffee
若要通知系統我們期望得到一個選項,我們使用 this.option()
方法。此方法接受一個 name
(字串)以及一個選項雜湊(選用)。
name
值會用來在符合鍵 this.options[name]
中擷取選項。
選項雜湊(第二個引數)接受多組關鍵字值對。
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('嘿!歡迎來到我超棒的產生器')
)。它會接收一個字串,並將其輸出給使用者;基本上,當在終端機工作階段中使用時,它會模擬 console.log()
。使用方法如下
module.exports = class extends Generator {
myAction() {
this.log("Something has gone wrong!");
}
};
你還可以在 API 文件 中找到一些其他輔助方法。