Angular中文博客

分享让你更聪明

[译2018]原理图——简介

浏览:54次 评论:0次 日期:2024年10月18日 22:18:38 作者:管理员

Schematics 是现代网络的工作流程工具;它可以将转换应用于您的项目,例如创建新组件,或更新代码以修复依赖项中的重大更改。或者您可能想向现有项目添加新的配置选项或框架。

目标

Angular CLI 的使命是提高您的开发效率。我们需要一个更强大、更通用的工具来支持 CLI 脚手架,我们确定了 4 个主要目标:

了解原理图

在示意图中,您实际上并不对文件系统执行任何直接操作。相反,您描述您想要对Tree应用什么转换。这使我们能够支持诸如试运行(或补丁运行)之类的功能,而无需从原理图本身添加特殊支持。它还使原理图密封,确保可重用性和安全性。

Tree是一种数据结构,包含基础(一组已存在的文件)和暂存区域(要应用于基础的更改列表)。进行修改时,您实际上并没有更改基础,而是将这些修改添加到暂存区域。这确实很强大,但可能很棘手,将在单独的媒体帖子中进一步探讨。

原理图将接收的Tree可以是任何东西。 Angular CLI 将使用Tree来表示驱动器上的项目到它调用的第一个原理图,但组合原理图可以接收任何Tree 。好消息是,这并不重要。 Tree代表您的起点。

创建您的第一个原理图

首先,确保您安装了 Node 6.9 或更高版本。接下来,全局安装 Schematics 命令行工具:

npm install -g @angular-devkit/schematics-cli

这将安装一个schematics可执行文件,您可以使用它来创建一个空白的原理图项目:

schematics blank --name=my-component

等等瞧。 blank原理图可以创建一个新项目,也可以将空白原理图添加到现有项目中(两者都可以使用)。然后,您可以cd进入新项目,安装 npm 依赖项,并使用您最喜欢的编辑器打开新集合:

cd my-component
npm install
code . # or atom, webstorm, vi, ...

收藏

原理图集合是一组命名原理图,由用户发布和安装。例如,Angular 团队发布并维护官方@schematics/angular集合,其中包含component 、 moduleapplication等原理图。

在我们的例子中,我们的集合将仅包括my-component原理图。你可以查看src/collection.json文件,其中包含我们集合的描述:

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "my-component": {
      "description": "A blank schematic.",
      "factory": "./my-component/index#myComponent"
    }
  }
}

$schema键指向定义此格式的 JSON 架构。它被 IDE 用于自动完成、验证工具,并且完全是可选的。

重要的关键是"schematics" ,它描述了该集合中包含的原理图。在我们的示例中,我们描述了一个原理图: my-component ,它有一个简单的描述和一个工厂字段。 factory字段使用字符串引用来指向 JavaScript 函数;在我们的例子中,导出函数myComponent在文件my-component/index.js中。它代表RuleFactory 。

规则、树和文件

Rule是一个函数,它接受一个Tree并返回另一个Tree 。规则是Schematics的核心;他们是对您的项目进行更改、调用外部工具和实现逻辑的人。 RuleFactory ,顾名思义,是创建Rule的函数。

这是迄今为止创建的空白RuleFactory :

// index.ts
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';


// You don't have to export the function as default. You can also have more than one rule factory
// per file.
export function myComponent(options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    return tree;
  };
}

该工厂接受一个options参数并返回一个Rule ,该规则接受一个Tree并返回它不变。

options参数是一个可以视为工厂输入的对象。在 CLI 中,它是用户传递的命令行参数。从另一个原理图来看,它是该原理图传入的选项。例如,GUI 工具可以根据用户或项目输入构建选项对象。

无论如何,这始终是一个对象,并且可以键入为any 。还可以使用 JSON 架构对其进行验证,以确保输入具有适当的默认值和类型。 JSON 模式将在后面的文章中更仔细地讨论。

与此同时,让我们用我们的规则做一些更有趣的事情:

// index.ts 

import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';


// You don't have to export the function as default. You can also have more than one rule factory
// per file.
export function myComponent(options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    tree.create(options.name || 'hello', 'world');
    return tree;
  };
}

通过这一新行,我们在原理图的Tree的根目录中创建一个文件,以name选项(默认情况下为'hello' )命名,包含字符串world 。目前看来这似乎微不足道,但背后却发生了很多事情。

Tree包含应应用原理图的文件。它有一个文件列表,并包含与您要应用的更改相关的元数据。在我们的例子中,所做的唯一更改是创建一个新文件。树比仅仅作为文件系统等价物更复杂,并将在后面的文章中更深入地探讨,但目前您可以将它们视为文件和更改的集合。

默认情况下,Angular CLI 会将 Angular 项目的根作为Tree传递,但任何原理图都可以将不同的Tree传递给其他原理图。您可以创建空树、将Tree范围限定为父Tree的目录、合并两棵树或对它们进行分支(制作其副本)。

有四种方法可以直接在Tree中创建更改; create 、 delete 、 renameoverwrite 。

运行您的新原理图

要运行我们的示例,您首先需要构建它,然后使用schematics命令行工具,并将原理图项目目录的路径作为集合。从我们项目的根源来看:

npm run build
# ... wait for build to finish
schematics .:my-component --name=test
# ... see that a file is created in the root.

在进一步研究这里发生的事情之前,先警告一下;别担心,这次您实际上并没有在文件系统上创建文件。这是因为当使用路径作为它应该使用的集合时, schematics工具处于调试模式。在调试时(也可以与--debug=true一起使用),默认情况下也是在试运行模式下运行,这会阻止该工具实际创建文件。

这可以使用参数--dry-run=false进行更改。但请注意,这意味着更改将真正发生在文件系统上。如果删除或覆盖文件,您可能会丢失您不想要的内容。我们建议在调试原理图时位于单独的临时目录中,并仅在必要时禁用试运行。

您还可以在单​​独的终端中启动npm run build -- -w以便在文件更改时自动重建原理图项目。

调试

为了调试原理图,您需要在调试模式下运行节点:

node --inspect-brk $(which schematics) .:myComponent --name=test

在调试模式下运行的另一个优点是schematics命令行工具在运行您自己的原理图之前直接放置一个断点。

调用另一个原理图

Schematics 的一大优势在于它们很容易组合在一起。在我们的示例中,我们将从 Angular 集合中调用component原理图,以将组件添加到您的应用程序中,然后向原理图添加的每个 TypeScript 文件添加标头。

// index.ts 
import { Rule, SchematicContext, Tree, chain, externalSchematic } from '@angular-devkit/schematics';

const licenseText = `
/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
`;

export function myComponent(options: any): Rule {
  return chain([
    externalSchematic('@schematics/angular', 'component', options),
    (tree: Tree, _context: SchematicContext) => {
      tree.getDir(options.sourceDir)
          .visit(filePath => {
            if (!filePath.endsWith('.ts')) {
              return;
            }
            const content = tree.read(filePath);
            if (!content) {
              return;
            }

            // Prevent from writing license to files that already have one.
            if (content.indexOf(licenseText) == -1) {
              tree.overwrite(filePath, licenseText + content);
            }
          });
      return tree;
    },
  ]);
}

不要忘记将@schematics/angular添加到package.json中的依赖项中!

这里有几点需要注意。首先,我们直接调用并返回chain() 。 chain()是 Schematics 库提供的一个RuleFactory ,它将多个规则链接在一起,并在规则之间等待Rule完成。 Schematic 库还提供了其他类似的规则工厂,我们稍后会详细介绍它们。

其次,我们使用另一个名为externalSchematicRuleFactory (它还有一个名为schematic的姊妹工厂)。原理图是规则,您可能会想简单地导入原理图的规则工厂并自己创建规则,然后直接调用它(或直接将其传递到链)。不要直接将其他 Schematics 称为Rule  externalSchematic (和schematic )规则工厂比导入原理图并运行它有更多的逻辑。例如,验证架构并填充默认值。

最后,目前没有好的方法来列出在树中创建或覆盖的文件。由于 Schematics 的构建是封闭的,因此您收到的Tree没有局部更改。因此,我们必须检查所有文件。

使用 Angular CLI

目前,用户使用 Schematics 的最佳方式是通过 Angular CLI。这意味着您应该在将其发布到 NPM 之前尝试一下。在这里,我们将尝试通过 Angular CLI 使用新的myComponent原理图。

首先,使用 CLI 创建一个空项目:

ng new my-project

然后在您的新项目中,链接我们刚刚构建的原理图:

npm link $PATH_TO_SCHEMATIC_PROJECT

$PATH_TO_SCHEMATIC_PROJECT替换为项目根目录的路径。请注意,用户将安装而不是链接,这只是为了在开发时在本地更快地迭代。

链接原理图项目后,您可以使用ng generate来调用原理图:

ng generate my-component:my-component someName

默认情况下,如果原理图采用name参数,则生成命​​令的第二个参数将设置为该名称。

瞧!这应该足以让您的用户开始使用。请注意,您还可以在 CLI 配置中设置一个默认集合。有关配置的更多信息,请参阅 CLI wiki。

结论

回顾一下到目前为止我们学到的东西:

在下一篇博客文章中,我将更深入地访问Tree数据结构,并查看任务,任务可用于以智能且安全的方式调用外部进程。

Schematics 是 Angular DevKit 更大努力的第一部分,未来将包含许多其他库,这些工作将在单独的帖子中描述。

欢呼,干杯!

文章来源地址:https://blog.angular.dev/schematics-an-introduction-dc1dfbc2a2b2

发表评论