7.1 定位
Yeoman文件实用程序基于这样的想法,在磁盘上始终有两个位置上下文。 这些上下文是Generator最有可能读取和写入的文件夹。
目标上下文(Destination Context)
第一个上下文是目标上下文。 “目标”是指Yeoman存放新应用程序的文件夹。 这是用户项目文件夹,在这编写大多数脚手架。
目标上下文定义为当前工作目录或包含.yo-rc.json文件的最近的父文件夹。.yo-rc.json文件定义了Yeoman项目的根目录。该文件允许用户在子目录中运行命令并可在项目上运行。这样可以确保最终用户的行为一致。
您可以使用this.destinationRoot() 或通过使用this.destinationPath('sub / path') 联接路径来获取目标路径。
class extends Generator {
paths() {
this.destinationRoot();
// returns '~/projects'
this.destinationPath('index.js');
// returns '~/projects/index.js'
}
}
您可以使用this.destinationRoot('new / path')进行手动设置。 但是为了保持一致性,不应该更改默认Destination。
如果您想知道用户在哪里运行yo,可以使用this.contextRoot获取路径。 在使用.yo-rc.json确定项目根目录之前,这个命令可以取得yo的原始路径。
模板上下文(Template Context)
模板上下文是用于存储模板文件的文件夹。 通常是您要从中读取和复制的文件夹。
默认情况下,模板上下文定义为./templates/。 您可以使用this.sourceRoot('new / template / path') 覆盖此默认值。
可以使用this.sourceRoot() 或通过使用this.templatePath('app / index.js') 连接路径来获取路径值。
class extends Generator {
paths() {
this.sourceRoot();
// returns './templates'
this.templatePath('index.js');
// returns './templates/index.js'
}
};
7.2 “内存”文件系统
Yeoman在覆盖用户文件时非常小心。基本上,对已存在的文件上写入时,都先解决冲突。 解决冲突时要求用户验证每个文件的(覆盖)写入。
这样,可防止出现意外情况并限制发生错误的风险。 另一方面,这意味着每个文件都异步写入磁盘。
由于异步API难以使用,因此Yeoman提供了一个同步文件系统API,其中每个文件都被写入内存文件系统,并且只有在Yeoman完成运行后才被写入磁盘。
这个内存文件系统在所有组合Generator之间共享。
7.3 文件工具
generator在this.fs上公开所有文件方法,此文件是mem-fs编辑器的实例-确保检查模块文档中所有可用的方法。
注意:尽管this.fs公开了commit,但不应在Generator中调用它。 在运行循环的冲突阶段之后,Yeoman在内部调用此方法。
例如:Copy一个模板文件
模板如下:
<html>
<head>
<title><%= title %></title>
</head>
</html>
然后,在将内容作为模板处理时,我们将使用copyTpl方法复制文件。 copyTpl使用ejs模板语法。
class extends Generator {
writing() {
this.fs.copyTpl(
this.templatePath('index.html'),
this.destinationPath('public/index.html'),
{ title: 'Templating with Yeoman' }
);
}
}
结果如下:
<html>
<head>
<title>Templating with Yeoman</title>
</head>
</html>
一个非常常见的方案是在提示阶段存储用户答案,并将其用于模板:
class extends Generator {
async prompting() {
this.answers = await this.prompt([{
type : 'input',
name : 'title',
message : 'Your project title',
}]);
}
writing() {
this.fs.copyTpl(
this.templatePath('index.html'),
this.destinationPath('public/index.html'),
{ title: this.answers.title } // user answer `title` used
);
}
}
7.4 通过流转换输出文件
generator系统允许每次写入文件时应用自定义过滤器。 完全可以自动美化文件,规范空格等。
每个Yeoman进程一次,我们会将每个修改过的文件写入磁盘。 任何生成器作者都可以注册transformStream来修改文件路径和内容。
通过registerTransformStream() 方法注册新的修饰符。 这是一个例子:
var beautify = require("gulp-beautify");
this.registerTransformStream(beautify({ indent_size: 2 }));
请注意,全部文件都将通过此流传递。 确保任何转换流都会通过不支持的文件。 诸如gulp-if或gulp-filter之类的工具将有助于过滤无效类型并将其传递。
基本上,可以在Yeoman转换流中使用任何gulp插件,以在编写阶段处理生成的文件。
7.5 提示:更新现有文件的内容
更新预先存在的文件并不容易。 最可靠的方法是解析文件AST(抽象语法树)并对其进行编辑。 这种解决方案的主要问题在于,编辑AST可能会很冗长且难以掌握。
一些流行的AST解析器是:
- Cheerio 用于解析HTML
- Esprima 用于解析JavaScript - 可能对 AST-Query 感兴趣,该查询提供了用于编辑Esprima语法树的较低级别的API。
- 对于Json文件,可以使用原生的
JSON
object methods. - Gruntfile Editor 用于动态修改Gruntfile。
使用RegEx解析代码文件很危险,在这样做之前,您应该阅读 CS anthropological answers 并掌握RegEx解析的缺陷。 如果确实选择使用RegEx而不是AST树来编辑现有文件,请小心并提供完整的单元测试。 注意:请不要破坏用户的代码。
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 |