一个现代Web的脚手架库。
Schematics 是一种生成器,可以转换现有的文件系统。它们可以创建文件、重构现有文件或移动文件。
与其他生成器(如 Yeoman 或 Yarn Create)不同的是,Schematics 是纯描述性的;在一切准备好提交之前,所有更改都不会应用到实际文件系统中。Schematics 设计上没有副作用。
| 术语 | 描述 |
|---|---|
| Schematics | 一种在现有文件系统上执行描述性代码且无副作用的生成器。 |
| Collection | 一组 Schematics 的元数据列表。可以在集合中通过名称引用 Schematics。 |
| Tool | 使用 Schematics 库的代码。 |
| Tree | 一个包含原始文件系统和一组要应用的更改的暂存区域。 |
| Rule | 一个对 Tree 应用操作的函数。它返回一个新的 Tree,其中包含所有要应用的转换。 |
| Source | 一个从空文件系统创建全新 Tree 的函数。例如,一个文件源可以从磁盘读取文件并为每个文件创建一个创建操作。 |
| Action | 要验证并提交到文件系统或 Tree 的原子操作。Actions 是由 Schematics 创建的。 |
| Sink | 所有 Action 的最终目的地。 |
| Task | 在 Schematics 中执行外部命令或脚本的一种方式。Task 可用于执行诸如安装依赖、运行测试或构建项目的操作。Task 是通过使用 SchematicContext 对象创建的,并且可以在应用 Schematics Tree 之前或之后运行。 |
Schematics 是一个库,本身无法独立运行。可以在此 参考 CLI 中找到它,并且可以在 NPM 上以 @angular-devkit/schematics-cli 的形式发布。本文档解释了库的用法和工具 API,但不涉及工具实现本身。
工具负责以下任务:
工具 API 由以下部分组成:
SchematicEngine 负责加载和构建 Collection 和 Schematics。在创建引擎时,工具提供一个 EngineHost 接口,该接口了解如何通过名称创建 CollectionDescription,以及如何创建 SchematicDescription。
Schematics 是生成器,是 Collection 的一部分。
一个 Collection 是由一个 collection.json 文件(在参考 CLI 中)定义的。此 JSON 定义了以下属性:
| 属性名称 | 类型 | 描述 |
|---|---|---|
| name | string |
Collection 的名称。 |
| version | string |
未使用的字段。 |
Source 是一个生成 Tree 的生成器;它从无到有创建一个全新的根 Tree。Rule 是从一个 Tree 到另一个 Tree 的转换。Schematic(在根目录)是一个通常应用于文件系统的 Rule。
FileOperator 应用更改到单个 FileEntry 并返回一个新的 FileEntry。结果遵循以下规则:
FileEntry 为 null,将在操作列表中添加一个 DeleteAction。RenameAction。OverwriteAction。通过 FileOperator 无法创建文件。
Schematics 库默认提供了多个 Operator 工厂,涵盖了基本用例:
| FileOperator | 描述 |
|---|---|
contentTemplate<T>(options: T) |
应用内容模板(见 模板化 部分) |
pathTemplate<T>(options: T) |
应用路径模板(见 模板化 部分) |
Schematics 库还默认提供了多个 Source 工厂:
| Source | 描述 |
|---|---|
empty() |
创建一个返回空 Tree 的 Source。 |
source(tree: Tree) |
创建一个返回传入的 Tree 作为参数的 Source。 |
url(url: string) |
从给定的 URL 加载文件列表,并返回一个包含这些文件作为 CreateAction 应用到空 Tree 的 Tree。 |
apply(source: Source, rules: Rule[]) |
将一组 Rule 应用到 Source 上,并返回结果 Source。 |
Schematics 库还默认提供了 Rule 工厂:
| Rule | 描述 |
|---|---|
noop() |
原样返回输入的 Tree。 |
chain(rules: Rule[]) |
返回一个由其他 Rule 组成的链式 Rule。 |
forEach(op: FileOperator) |
返回一个对输入 Tree 的每个文件应用操作符的 Rule。 |
move(root: string) |
将输入中的所有文件移动到子目录。 |
merge(other: Tree) |
将输入的 Tree 与其他 Tree 合并。 |
contentTemplate<T>(options: T) |
将内容模板应用到整个 Tree(见模板部分)。 |
pathTemplate<T>(options: T) |
将路径模板应用到整个 Tree(见模板部分)。 |
template<T>(options: T) |
同时将路径和内容模板应用到整个 Tree(见模板部分)。 |
filter(predicate: FilePredicate<boolean>) |
返回包含通过 FilePredicate 的文件的输入 Tree。 |
如上所述,一些函数基于文件模板化系统,它包括路径和内容模板化。
系统根据在 Tree 中加载的文件或其路径内定义的占位符进行操作,并按以下定义用传入 Rule 的值填充这些占位符(即 template<T>(options: T))。
| 占位符 | 描述 |
|---|---|
__variable__ |
替换为 variable 的值。 |
__variable@function__ |
替换为调用 function(variable) 的结果。可以向左链式调用(__variable@function1@function2__ 等)。 |
| 占位符 | 描述 |
|---|---|
<%= expression %> |
替换为调用给定表达式的结果。这仅支持直接表达式,不支持结构化(for/if/...)JavaScript。 |
<%- expression %> |
同上,但插入时结果将进行 HTML 转义(即替换 '<' 为 '\<')。 |
<% inline code %> |
将给定代码插入到模板结构中,允许插入结构化 JavaScript。 |
<%# text %> |
注释,会被完全删除。 |
一个简单的 Schematics 示例,它创建一个 "hello world" 文件,并使用一个选项来确定其路径:
import { Tree } from '@angular-devkit/schematics';
export default function MySchematic(options
: any) {
return (tree: Tree) => {
tree.create(options.path + '/hi', 'Hello world!');
return tree;
};
}
从这个示例中可以看到:
Rule,该 Rule 是从 Tree 到另一个 Tree 的转换。一个简化的 Schematics 示例,它创建一个包含新类的文件,并使用一个选项来确定其名称:
// files/__name@dasherize__.ts
export class <%= classify(name) %> {
}
// index.ts
import { strings } from '@angular-devkit/core';
import {
Rule,
SchematicContext,
SchematicsException,
Tree,
apply,
branchAndMerge,
mergeWith,
template,
url,
} from '@angular-devkit/schematics';
import { Schema as ClassOptions } from './schema';
export default function (options: ClassOptions): Rule {
return (tree: Tree, context: SchematicContext) => {
if (!options.name) {
throw new SchematicsException('Option (name) is required.');
}
const templateSource = apply(url('./files'), [
template({
...strings,
...options,
}),
]);
return branchAndMerge(mergeWith(templateSource));
};
}
从这个示例中可以看到的其他内容:
strings 提供了用于 dasherize 和 classify 等功能的函数。index.ts 相同的根目录中,并被加载到 Tree 中。template Rule 根据指定的模板占位符填充内容。为此,它只知道通过选项对象传递给它的变量和函数。Tree 被合并到运行该 Schematic 的项目的现有文件中。