每次运行生成器时,实际上都在使用yeoman-environment
。环境是一个与任何 UI 组件分离的基础系统,可以被任何工具抽象出来。当运行yo
时,基本上只是在核心 Yeoman 环境之上运行一个终端 UI 外观。
基础知识
首先需要知道的是,环境系统包含在yeoman-environment
包中。可以通过运行以下命令安装它:
npm install --save yeoman-environment
此模块提供了检索已安装生成器、注册和运行生成器的方法。它还提供了生成器使用的用户界面适配器。我们提供了完整 API 文档(即可用方法的简要列表)。
使用yeoman-environment
一个简单的使用示例
在深入讨论其他主题之前,让我们先看一个yeoman-environment
的简单使用示例。
在这个示例中,假设npm
希望提供一个npm init
命令来搭建一个package.json
。阅读文档的其他页面,您已经知道如何创建生成器 - 因此,让我们假设我们已经有了generator-npm
。我们将了解如何调用它。
第一步是实例化一个新的环境实例。
var yeoman = require('yeoman-environment');
var env = yeoman.createEnv();
然后,我们将希望注册我们的generator-npm
,以便以后可以使用它。这里有两个选择
// Here we register a generator based on its path. Providing the namespace
// is optional.
env.register(require.resolve('generator-npm'), 'npm:app');
// Or you can provide a generator constructor. Doing so, you need to provide
// a namespace manually
var GeneratorNPM = generators.Base.extend(/* put your methods in here */);
env.registerStub(GeneratorNPM, 'npm:app');
请注意,您可以注册任意数量的生成器。已注册的生成器仅在整个环境中可用(例如,允许组合)。
此时,您的环境已准备好运行npm:app
。
// In its simplest form
env.run('npm:app', done);
// Or passing arguments and options
env.run('npm:app some-name', { 'skip-install': true }, done);
就是这样。您只需要将此代码放在一个bin
可运行文件中,就可以在不使用yo
的情况下运行 Yeoman 生成器。
查找已安装的生成器
但是,如果您希望访问用户机器上安装的每个 Yeoman 生成器,该怎么办?然后您需要执行用户磁盘的查找。
env.lookup(function () {
env.run('angular');
});
Environment#lookup()
接受一个回调函数,一旦 Yeoman 完成搜索已安装的生成器,就会调用该回调函数。每个找到的生成器都将在环境中注册。
如果发生命名空间冲突,本地生成器将覆盖全局生成器。
获取有关已注册生成器的数据
调用Environment#getGeneratorsMeta()
将返回一个对象,描述查找任务注册的元数据。
每个对象的键都是一个生成器命名空间,而值对象包含以下键
resolved
:生成器的解析路径namespace
:生成器的命名空间
例如
{
"webapp:app": {
"resolved": "/usr/lib/node_modules/generator-webapp/app/index.js",
"namespace": "webapp:app"
}
}
注意:使用#registerStub()
注册的生成器将具有"unknown"
作为resolved
值。
提供自定义用户界面 (UI)
Yeoman 使用适配器作为抽象层,以允许 IDE、代码编辑器等轻松提供运行生成器所需的界面。
适配器是负责处理所有用户交互的对象。如果希望提供与经典命令行不同的交互模型,则必须编写自己的适配器。每个与用户交互的方法都通过此适配器传递(主要:提示、记录和差异)。
默认情况下,Yeoman 提供了一个终端适配器。我们的测试助手提供了一个测试适配器,它模拟提示并静默输出。您可以将这些用作自己实现的参考。
要安装适配器,请使用yeoman.createEnv(args, opts, adapter)
的第三个参数。
适配器至少应提供三种方法。
Adapter#prompt()
它提供了问答功能(例如,当启动yo
时,会向用户提示一组可能的动作)。其签名和行为遵循Inquirer.js。当生成器调用this.prompt
时,该调用最终由适配器处理。
Adapter#diff()
在遇到冲突并且用户请求查看旧文件和新文件之间的差异时(两个文件内容都作为参数传递)内部调用。
Adapter#log()
它既是一个函数,也是一个用于通用输出的对象。有关要提供的完整方法列表,请参阅lib/util/log.js
。
示例实现
以下列出了使用yeoman-environment
的模块/插件/应用程序。您可以将它们用作灵感。