填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

創作原理圖

Authoring schematics

你可以建立自己的原理圖來對 Angular 專案進行操作。函式庫開發人員通常會把這些原理圖與他們的函式庫打包在一起,以便把它們與 Angular CLI 整合在一起。你也可以建立獨立的原理圖來操作 Angular 應用中的檔案和目錄結構,以便為你的開發環境訂製它們,並讓它們符合你的標準和約束。多個原理圖還可以串聯起來,透過執行其它原理圖來完成複雜的操作。

You can create your own schematics to operate on Angular projects. Library developers typically package schematics with their libraries in order to integrate them with the Angular CLI. You can also create stand-alone schematics to manipulate the files and constructs in Angular applications as a way of customizing them for your development environment and making them conform to your standards and constraints. Schematics can be chained, running other schematics to perform complex operations.

在應用程式中操作程式碼可能既強大又危險。例如,建立一個已存在的檔案會出錯,如果出現這種情況,就應該放棄已應用的所有其它更改。Angular 原理圖工具透過建立虛擬檔案系統來防止副作用和錯誤。原理圖描述了一個可應用於虛擬檔案系統的轉換管道。當原理圖執行時,轉換就會被記錄在記憶體中,只有當這些更改被確認有效時,才會應用到實際的檔案系統中。

Manipulating the code in an application has the potential to be both very powerful and correspondingly dangerous. For example, creating a file that already exists would be an error, and if it was applied immediately, it would discard all the other changes applied so far. The Angular Schematics tooling guards against side effects and errors by creating a virtual file system. A schematic describes a pipeline of transformations that can be applied to the virtual file system. When a schematic runs, the transformations are recorded in memory, and only applied in the real file system once they're confirmed to be valid.

原理圖的概念

Schematics concepts

原理圖的公共 API 定義了表達其基本概念的類別。

The public API for schematics defines classes that represent the basic concepts.

  • 虛擬檔案系統用 Tree(樹)表示。Tree 資料結構包含一個基礎狀態 base(一組已經存在的檔案)和一個 暫存區 staging(需要應用到 base 的更改列表)。在進行修改的過程中,你並沒有真正改變它的 base,而是把那些修改新增到了暫存區。

    The virtual file system is represented by a Tree. The Tree data structure contains a base (a set of files that already exists) and a staging area (a list of changes to be applied to the base). When making modifications, you don't actually change the base, but add those modifications to the staging area.

  • Rule(規則)物件定義了一個函式,它接受 Tree,進行轉換,並返回一個新的 Tree。原理圖的主檔案 index.ts 定義了一組實現原理圖邏輯的規則。

    A Rule object defines a function that takes a Tree, applies transformations, and returns a new Tree. The main file for a schematic, index.ts, defines a set of rules that implement the schematic's logic.

  • 轉換由 Action(動作)表示。有四種動作型別:CreateRenameOverwriteDelete

    A transformation is represented by an Action. There are four action types: Create, Rename, Overwrite, and Delete.

  • 每個原理圖都在一個上下文中執行,上下文由一個 SchematicContext 物件表示。

    Each schematic runs in a context, represented by a SchematicContext object.

傳給規則的上下文物件可以訪問該原理圖可能會用到的工具函式和元資料,包括一個幫助除錯的日誌 API。上下文還定義了一個合併策略,用於確定如何將這些更改從暫存樹合併到基礎樹中。可以接受或忽略某個更改,也可以丟擲異常。

The context object passed into a rule provides access to utility functions and metadata that the schematic may need to work with, including a logging API to help with debugging. The context also defines a merge strategy that determines how changes are merged from the staged tree into the base tree. A change can be accepted or ignored, or throw an exception.

定義規則和動作

Defining rules and actions

當你使用 Schematics CLI 建立一個新的空白原理圖時,它所產生的入口函式就是一個規則工廠RuleFactory 物件定義了一個用於建立 Rule 的高階函式。

When you create a new blank schematic with the Schematics CLI, the generated entry function is a rule factory. A RuleFactory object defines a higher-order function that creates a Rule.

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 helloWorld(_options: any): Rule {
 return (tree: Tree, _context: SchematicContext) => {
   return tree;
 };
}
    

你的這些規則可以透過呼叫外部工具和實現邏輯來修改你的專案。比如,你需要一個規則來定義如何將原理圖中的範本合併到宿主專案中。

Your rules can make changes to your projects by calling external tools and implementing logic. You need a rule, for example, to define how a template in the schematic is to be merged into the hosting project.

規則可以利用 @schematics/angular 套件提供的實用工具。尋求輔助函式來處理模組、依賴、TypeScript、AST、JSON、Angular CLI 工作區和專案等等。

Rules can make use of utilities provided with the @schematics/angular package. Look for helper functions for working with modules, dependencies, TypeScript, AST, JSON, Angular CLI workspaces and projects, and more.

index.ts
      
      import {
  JsonAstObject,
  JsonObject,
  JsonValue,
  Path,
  normalize,
  parseJsonAst,
  strings,
} from '@angular-devkit/core';
    

利用模式和介面來定義輸入選項

Defining input options with a schema and interfaces

規則可以從呼叫者那裡收集選項值,並把它們注入到範本中。規則可用的選項及其允許的值和預設值是在原理圖的 JSON 模式檔案 <schematic>/schema.json 中定義的。你可以使用 TypeScript 介面來為這個模式定義變數或列舉的資料型別。

Rules can collect option values from the caller and inject them into templates. The options available to your rules, with their allowed values and defaults, are defined in the schematic's JSON schema file, <schematic>/schema.json. You can define variable or enumerated data types for the schema using TypeScript interfaces.

該模式定義了原理圖中使用的變數的型別和預設值。例如,假設的 “Hello World” 原理圖可能具有以下模式定義(schema)。

The schema defines the types and default values of variables used in the schematic. For example, the hypothetical "Hello World" schematic might have the following schema.

src/hello-world/schema.json
      
      {
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "default": "world"
        },
        "useColor": {
            "type": "boolean"
        }
    }
}
    

你可以在 @schematics/angular中看到 Angular CLI 命令原理圖的模式檔案範例。

You can see examples of schema files for the Angular CLI command schematics in @schematics/angular.

原理圖提示

Schematic prompts

原理圖提示能將使用者互動引入到原理圖執行過程中。你可以配置原理圖選項,以向用戶顯示可自訂的問題。 在執行原理圖之前會顯示提示,然後將使用者的響應用作選項的值。這使得使用者可以指導原理圖的操作,而無需深入瞭解可用選項的全部範圍。

Schematic prompts introduce user interaction into schematic execution. You can configure schematic options to display a customizable question to the user. The prompts are displayed before the execution of the schematic, which then uses the response as the value for the option. This allows users to direct the operation of the schematic without requiring in-depth knowledge of the full spectrum of available options.

例如,這個 “Hello World” 原理圖可能會要求使用者提供他的名字,並顯示該名字以代替預設名字 “world”。要定義這樣的提示,請將 x-prompt 屬性新增到 name 變數的模式中。

The "Hello World" schematic might, for example, ask the user for their name, and display that name in place of the default name "world". To define such a prompt, add an x-prompt property to the schema for the name variable.

類似地,你可以新增一個提示,以允許使用者確定原理圖在執行其 hello 操作時是否將使用顏色。帶有兩個提示的模式如下。

Similarly, you can add a prompt to allow the user to decide whether the schematic will use color when executing its hello action. The schema with both prompts would be as follows.

src/hello-world/schema.json
      
      {
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "default": "world",
            "x-prompt": "What is your name?"
        },
        "useColor": {
            "type": "boolean",
            "x-prompt": "Would you like the response in color?"
        }
    }
}
    

提示的簡寫語法

Prompt short-form syntax

這些範例使用提示語法的簡寫形式,僅提供問題的文字。在大多數情況下,這就是所需要的。但是請注意,這兩個提示要求使用不同型別的輸入。使用簡寫形式時,將根據屬性的模式自動選擇最合適的型別。在該範例中,name 提示使用 input 型別,因為它是一個字串屬性。useColor 提示使用 confirmation 型別,因為它是布林屬性。在這種情況下,“是” 對應於 true 而 “否” 對應於 false

These examples use a shorthand form of the prompt syntax, supplying only the text of the question. In most cases, this is all that is required. Notice however, that the two prompts expect different types of input. When using the shorthand form, the most appropriate type is automatically selected based on the property's schema. In the example, the name prompt uses the input type because it it is a string property. The useColor prompt uses a confirmation type because it is a Boolean property. In this case, "yes" corresponds to true and "no" corresponds to false.

支援三種輸入型別。

There are three supported input types.

輸入型別

Input type

描述

Description

確認

confirmation

是或否的問題;布林選項的理想選擇。

A yes or no question; ideal for Boolean options.

輸入

input

文字輸入;字串或數字選項的理想選擇。

Textual input; ideal for string or number options.

清單

list

預定義的一組允許值。

A predefined set of allowed values.

簡而言之,型別是根據屬性的型別和約束來推斷的。

In the short form, the type is inferred from the property's type and constraints.

屬性模式

Property Schema

提示型別

Prompt Type

"type": "boolean"

確認(“yes” = true,“no” = false

confirmation ("yes"=true, "no"=false)

"type": "string"

輸入

input

"type": "number"

輸入(僅接受有效數字)

input (only valid numbers accepted)

"type": "integer"

輸入(僅接受有效數字)

input (only valid numbers accepted)

"enum": [...]

列表(列舉成員成為列表中的選擇項)

list (enum members become list selections)

在以下範例中,該屬性採用列舉值,因此原理圖將自動選擇列表型別,並根據可能的值建立選單。

In the following example, the property takes an enumerated value, so the schematic automatically chooses the list type, and creates a menu from the possible values.

schema.json
      
      "style": {
  "description": "The file extension or preprocessor to use for style files.",
  "type": "string",
  "default": "css",
  "enum": [
    "css",
    "scss",
    "sass",
    "less",
    "styl"
  ],
  "x-prompt": "Which stylesheet format would you like to use?"
}
    

提示執行時會根據 JSON 模式中提供的約束條件自動驗證提供的響應。如果該值不可接受,則提示使用者輸入新值。這樣可以確保傳遞到原理圖的任何值都符合原理圖實現的期望,因此你無需在原理圖的程式碼中新增其它檢查。

The prompt runtime automatically validates the provided response against the constraints provided in the JSON schema. If the value is not acceptable, the user is prompted for a new value. This ensures that any values passed to the schematic meet the expectations of the schematic's implementation, so that you do not need to add additional checks within the schematic's code.

提示的長格式語法

Prompt long-form syntax

在需要對提示進行其它自訂和控制情況下,x-prompt 欄位也支援長格式語法。在這種形式下,x-prompt 欄位值是帶有子欄位的 JSON 物件,這些子欄位可自訂提示的行為。

The x-prompt field syntax supports a long form for cases where you require additional customization and control over the prompt. In this form, the x-prompt field value is a JSON object with subfields that customize the behavior of the prompt.

欄位

Field

資料值

Data Value

type

confirmationinputlist (以簡短形式自動選擇)

confirmation, input, or list (selected automatically in short form)

message

字串(必填)

string (required)

items

字串和/或“標籤/值”物件(僅對 list 型別有效)

string and/or label/value object pair (only valid with type list)

下面的長格式範例來自 CLI 用來產生應用程式的原理圖的 JSON 模式。它定義提示,允許使用者選擇要用於正在建立的應用程式的樣式前處理器。透過使用長格式,原理圖可以為選單選項提供更明確的格式。

The following example of the long form is from the JSON schema for the schematic that the CLI uses to generate applications. It defines the prompt that allows users to choose which style preprocessor they want to use for the application being created. By using the long form, the schematic can provide more explicit formatting of the menu choices.

package/schematics/angular/application/schema.json
      
      "style": {
  "description": "The file extension or preprocessor to use for style files.",
  "type": "string",
  "default": "css",
  "enum": [
    "css",
    "scss",
    "sass",
    "less",
    "styl"
  ],
  "x-prompt": {
    "message": "Which stylesheet format would you like to use?",
    "type": "list",
    "items": [
      { "value": "css",  "label": "CSS" },
      { "value": "scss", "label": "SCSS   [ https://sass-lang.com/documentation/syntax#scss                ]" },
      { "value": "sass", "label": "Sass   [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]" },
      { "value": "less", "label": "Less   [ http://lesscss.org/                                            ]" },
      { "value": "styl", "label": "Stylus [ https://stylus-lang.com/                                       ]" }
    ]
  },
},
    

x-prompt 模式

x-prompt schema

定義原理圖選項的 JSON 模式支援擴充套件,以允許對提示及其相應行為進行宣告式定義。無需其它邏輯或更改原理圖程式碼即可支援提示。以下 JSON 模式是 x-prompt 欄位的長格式語法的完整描述。

The JSON schema that defines a schematic's options supports extensions to allow the declarative definition of prompts and their respective behavior. No additional logic or changes are required to the code of a schematic to support the prompts. The following JSON schema is a complete description of the long-form syntax for the x-prompt field.

x-prompt schema
      
      {
    "oneOf": [
        { "type": "string" },
        {
            "type": "object",
            "properties": {
                "type": { "type": "string" },
                "message": { "type": "string" },
                "items": {
                    "type": "array",
                    "items": {
                        "oneOf": [
                            { "type": "string" },
                            {
                                "type": "object",
                                "properties": {
                                    "label": { "type": "string" },
                                    "value": { }
                                },
                                "required": [ "value" ]
                            }
                        ]
                    }
                }
            },
            "required": [ "message" ]
        }
    ]
}
    

原理圖 CLI

Schematics CLI

原理圖有自己的命令列工具。使用 Node 6.9 或以上版本,全域性安裝 Schematics 命令列工具:

Schematics come with their own command-line tool. Using Node 6.9 or above, install the Schematics command line tool globally:

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

這將安裝可執行檔案 schematics,你可以用它在自己的專案資料夾中建立一個新的原理圖集合、把一個新的原理圖新增到一個現有的集合中,或者擴充套件一個現有的原理圖。

This installs the schematics executable, which you can use to create a new schematics collection in its own project folder, add a new schematic to an existing collection, or extend an existing schematic.

在下面的章節中,我們將使用 CLI 建立一個新的原理圖集合,以介紹檔案和目錄結構,以及一些基本概念。

In the following sections, we will create a new schematics collection using the CLI in order to introduce the files and file structure, and some of the basic concepts.

但是,原理圖的最常見用途是將 Angular 函式庫與 Angular CLI 整合在一起。你可以直接在 Angular 工作區的函式庫專案中建立原理圖檔案,而無需使用 Schematics CLI。參閱函式庫的原理圖

The most common use of schematics, however, is to integrate an Angular library with the Angular CLI. You can do this by creating the schematic files directly within the library project in an Angular workspace, without using the Schematics CLI. See Schematics for Libraries.

建立一個原理圖的集合

Creating a schematics collection

下列命令用來在同名的新專案資料夾中建立一個名為 hello-world 的新原理圖。

The following command creates a new schematic named hello-world in a new project folder of the same name.

      
      schematics blank --name=hello-world
    

blank 原理圖是由 Schematics CLI 提供的。該命令用於建立一個新的專案資料夾(該集合的根資料夾),並在該集合中建立一個最初的命名原理圖。

The blank schematic is provided by the Schematics CLI. The command creates a new project folder (the root folder for the collection) and an initial named schematic in the collection.

轉到 collection 資料夾,安裝你的 npm 依賴,然後在常用的編輯器中開啟這個新集合,看看所產生的檔案。例如,如果你正在使用 VSCode:

Go to the collection folder, install your npm dependencies, and open your new collection in your favorite editor to see the generated files. For example, if you are using VSCode:

      
      cd hello-world
npm install
npm run build
code .
    

最初的原理圖與專案資料夾的名字相同,是在 src/hello-world 中產生的。你可以把相關的原理圖新增到這個集合中,並修改所產生的骨架程式碼來定義原理圖的功能。每個原理圖的名稱在集合中都必須是唯一的。

The initial schematic gets the same name as the project folder, and is generated in src/hello-world. You can add related schematics to this collection, and modify the generated skeleton code to define your schematic's functionality. Each schematic name must be unique within the collection.

執行原理圖

Running a schematic

使用 schematics 命令執行一個命名原理圖。按以下格式提供專案資料夾的路徑、原理圖名稱和所有必選項。

Use the schematics command to run a named schematic. Provide the path to the project folder, the schematic name, and any mandatory options, in the following format.

      
      schematics <path-to-schematics-project>:<schematics-name> --<required-option>=<value>
    

該路徑可以是絕對路徑,也可以是執行該命令的當前工作目錄的相對路徑。例如,要執行我們剛產生的原理圖(它沒有必選項),請使用下面的命令。

The path can be absolute or relative to the current working directory where the command is executed. For example, to run the schematic we just generated (which has no required options), use the following command.

      
      schematics .:hello-world
    

把原理圖新增到集合中

Adding a schematic to a collection

要把一個原理圖新增到現有的集合中,請使用和新建原理圖專案相同的命令,不過要改為在該專案的資料夾下執行該命令。

To add a schematic to an existing collection, use the same command you use to start a new schematics project, but run the command inside the project folder.

      
      cd hello-world
schematics blank --name=goodbye-world
    

該命令會在你的集合中產生一個新的命名原理圖,它包含一個主檔案 index.ts 及其相關的測試規約。它還會把這個新原理圖的名字(name),說明(description)和工廠函式(factory function)新增到 collection.json 檔案中此集合的 JSON 模式中。

The command generates the new named schematic inside your collection, with a main index.ts file and its associated test spec. It also adds the name, description, and factory function for the new schematic to the collection's schema in the collection.json file.

集合的內容

Collection contents

集合的根資料夾中包含一些配置檔案、node_modules 資料夾和 src/ 資料夾。src/ 資料夾包含該集合中各個命名原理圖的子資料夾,以及一個模式檔案(collection.json),它是集合中各個原理圖的模式定義。每個原理圖都是用名稱,描述和工廠函式建立的。

The top level of the root project folder for a collection contains configuration files, a node_modules folder, and a src/ folder. The src/ folder contains subfolders for named schematics in the collection, and a schema, collection.json, which describes the collected schematics. Each schematic is created with a name, description, and factory function.

      
      {
  "$schema":
     "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "hello-world": {
      "description": "A blank schematic.",
      "factory": "./hello-world/index#helloWorld"
    }
  }
}
    
  • $schema 屬性指定了 CLI 進行驗證時所用的模式。

    The $schema property specifies the schema that the CLI uses for validation.

  • schematics 屬性列出了屬於這個集合的各個命名原理圖。每個原理圖都有一個純文字格式的描述,以及指向主檔案中自動產生的那個入口函式。

    The schematics property lists named schematics that belong to this collection. Each schematic has a plain-text description, and points to the generated entry function in the main file.

  • factory 屬性指向自動產生的那個入口函式。在這個例子中,你會透過呼叫 helloWorld() 工廠函式來呼叫 hello-world 原理圖。

    The factory property points to the generated entry function. In this example, you invoke the hello-world schematic by calling the helloWorld() factory function.

  • 可選屬性 schema 是一個 JSON 模式檔案,它定義了本原理圖中可用的命令列引數。

    The optional schema property points to a JSON schema file that defines the command-line options available to the schematic.

  • 可選陣列屬性 aliases 指定了一個或多個可用來呼叫此原理圖的字串。比如,Angular CLI “generate” 命令的原理圖有一個別名 “g”,這就可以讓你使用命令 ng g

    The optional aliases array specifies one or more strings that can be used to invoke the schematic. For example, the schematic for the Angular CLI “generate” command has an alias “g”, allowing you to use the command ng g.

命名原理圖

Named schematics

當你使用 Schematics CLI 建立空白原理圖專案時,該集合的第一個成員是一張與該集合同名的空白原理圖。當你把這個新的命名原理圖新增到本集合中時,它會自動新增到 collection.json 模式中。

When you use the Schematics CLI to create a blank schematics project, the new blank schematic is the first member of the collection, and has the same name as the collection. When you add a new named schematic to this collection, it is automatically added to the collection.json schema.

除了名稱和描述外,每個原理圖還有一個 factory 屬性,用於標識此原理圖的入口點。在本例中,你透過在主檔案 hello-world/index.ts 中呼叫 helloWorld() 函式來呼叫此原理圖中定義的功能。

In addition to the name and description, each schematic has a factory property that identifies the schematic’s entry point. In the example, you invoke the schematic's defined functionality by calling the helloWorld() function in the main file, hello-world/index.ts.

該集合中每個命名原理圖都有以下主要部分。

Each named schematic in the collection has the following main parts.

index.ts

定義命名原理圖中轉換邏輯的程式碼。

Code that defines the transformation logic for a named schematic.

schema.json

原理圖變數定義。

Schematic variable definition.

schema.d.ts

原理圖變數。

Schematic variables.

files/

要複製的可選元件/範本檔案。

Optional component/template files to replicate.

原理圖可以在 index.ts 檔案中提供它全部的邏輯,不需要額外的範本。你也可以在 files/ 資料夾中提供元件和範本來為 Angular 建立動態原理圖,比如那些獨立的 Angular 專案。這個 index 檔案中的邏輯會透過定義一些用來注入資料和修改變數的規則來配置這些範本。

It is possible for a schematic to provide all of its logic in the index.ts file, without additional templates. You can create dynamic schematics for Angular, however, by providing components and templates in the files/ folder, like those in standalone Angular projects. The logic in the index file configures these templates by defining rules that inject data and modify variables.