Angular 創(chuàng)作原理圖

2022-07-18 09:50 更新

創(chuàng)作原理圖

你可以創(chuàng)建自己的原理圖來對 Angular 項目進行操作。庫開發(fā)人員通常會把這些原理圖與他們的庫打包在一起,以便把它們與 Angular CLI 集成在一起。你也可以創(chuàng)建獨立的原理圖來操作 Angular 應(yīng)用中的文件和目錄結(jié)構(gòu),以便為你的開發(fā)環(huán)境定制它們,并讓它們符合你的標準和約束。多個原理圖還可以串聯(lián)起來,通過運行其它原理圖來完成復(fù)雜的操作。

在應(yīng)用程序中操作代碼可能既強大又危險。比如,創(chuàng)建一個已存在的文件會出錯,如果出現(xiàn)這種情況,就應(yīng)該放棄已應(yīng)用的所有其它更改。Angular 原理圖工具通過創(chuàng)建虛擬文件系統(tǒng)來防止副作用和錯誤。原理圖描述了一個可應(yīng)用于虛擬文件系統(tǒng)的轉(zhuǎn)換管道。當原理圖運行時,轉(zhuǎn)換就會被記錄在內(nèi)存中,只有當這些更改被確認有效時,才會應(yīng)用到實際的文件系統(tǒng)中。

原理圖的概念

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

  • 虛擬文件系統(tǒng)用 ?Tree?(樹)表示。?Tree ?數(shù)據(jù)結(jié)構(gòu)包含一個基礎(chǔ)狀態(tài) base(一組已經(jīng)存在的文件)和一個 暫存區(qū) staging(需要應(yīng)用到 base 的更改列表)。在進行修改的過程中,你并沒有真正改變它的 base,而是把那些修改添加到了暫存區(qū)。
  • ?Rule?(規(guī)則)對象定義了一個函數(shù),它接受 ?Tree?,進行轉(zhuǎn)換,并返回一個新的 ?Tree?。原理圖的主文件 ?index.ts? 定義了一組實現(xiàn)原理圖邏輯的規(guī)則。
  • 轉(zhuǎn)換由 ?Action?(動作)表示。有四種動作類型:?Create?、?Rename?、?Overwrite ?和 ?Delete?。
  • 每個原理圖都在一個上下文中運行,上下文由一個 ?SchematicContext ?對象表示。

傳給規(guī)則的上下文對象可以訪問該原理圖可能會用到的工具函數(shù)和元數(shù)據(jù),包括一個幫助調(diào)試的日志 API。上下文還定義了一個合并策略,用于確定如何將這些更改從暫存樹合并到基礎(chǔ)樹中??梢越邮芑蚝雎阅硞€更改,也可以拋出異常。

定義規(guī)則和動作

當你使用 Schematics CLI 創(chuàng)建一個新的空白原理圖時,它所生成的入口函數(shù)就是一個規(guī)則工廠。?RuleFactory ?對象定義了一個用于創(chuàng)建 ?Rule ?的高階函數(shù)。

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;
 };
}

你的這些規(guī)則可以通過調(diào)用外部工具和實現(xiàn)邏輯來修改你的項目。比如,你需要一個規(guī)則來定義如何將原理圖中的模板合并到宿主項目中。

規(guī)則可以利用 ?@schematics/angular? 包提供的實用工具。尋求輔助函數(shù)來處理模塊、依賴、TypeScript、AST、JSON、Angular CLI 工作區(qū)和項目等等。

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

利用模式和接口來定義輸入選項

規(guī)則可以從調(diào)用者那里收集選項值,并把它們注入到模板中。規(guī)則可用的選項及其允許的值和默認值是在原理圖的 JSON 模式文件 ?<schematic>/schema.json? 中定義的。可以用 TypeScript 接口來為這個模式定義變量或枚舉的數(shù)據(jù)類型。

該模式定義了原理圖中使用的變量的類型和默認值。比如,假設(shè)的 “Hello World” 原理圖可能具有以下模式定義(schema)。

{
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "default": "world"
        },
        "useColor": {
            "type": "boolean"
        }
    }
}

可以在 @schematics/angular 中看到 Angular CLI 命令原理圖的模式文件范例。

原理圖提示

原理圖提示能將用戶交互引入到原理圖執(zhí)行過程中??梢耘渲迷韴D選項,以向用戶顯示可自定義的問題。在執(zhí)行原理圖之前會顯示提示,然后將用戶的響應(yīng)用作選項的值。這使得用戶可以指導原理圖的操作,而無需深入了解可用選項的全部范圍。

比如,這個 “Hello World” 原理圖可能會要求用戶提供他的名字,并顯示該名字以代替默認名字 “world”。要定義這樣的提示,請將 ?x-prompt? 屬性添加到 ?name ?變量的模式中。

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

{
    "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?"
        }
    }
}

提示的簡寫語法

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

支持三種輸入類型。

輸入類型

詳情

確認

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

輸入

文字輸入;字符串或數(shù)字選項的理想選擇。

清單

預(yù)定義的一組允許值。

簡而言之,類型是根據(jù)屬性的類型和約束來推斷的。

屬性模式

提示類型

"type": "boolean"

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

"type": "string"

輸入

"type": "number"

輸入(僅接受有效數(shù)字)

"type": "integer"

輸入(僅接受有效數(shù)字)

"enum": […]

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

在以下范例中,該屬性采用枚舉值,因此原理圖將自動選擇列表類型,并根據(jù)可能的值創(chuàng)建菜單。

"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?"
}

提示運行時會根據(jù) JSON 模式中提供的約束條件自動驗證提供的響應(yīng)。如果該值不可接受,則提示用戶輸入新值。這樣可以確保傳遞到原理圖的任何值都符合原理圖實現(xiàn)的期望,因此你無需在原理圖的代碼中添加其它檢查。

提示的長格式語法

在需要對提示進行其它自定義和控制情況下,?x-prompt? 字段也支持長格式語法。在這種形式下,?x-prompt? 字段值是帶有子字段的 JSON 對象,這些子字段可自定義提示的行為。

字段

數(shù)據(jù)值

type

confirmation,input 或 list(以簡短形式自動選擇)

message

字符串(必填)

items

字符串和/或“標簽/值”對象(僅對 list 類型有效)

下面的長格式范例來自 CLI 用來生成應(yīng)用程序的原理圖的 JSON 模式。它定義提示,允許用戶選擇要用于正在創(chuàng)建的應(yīng)用程序的樣式預(yù)處理器。通過使用長格式,原理圖可以為菜單選項提供更明確的格式。

"style": {
  "description": "The file extension or preprocessor to use for style files.",
  "type": "string",
  "default": "css",
  "enum": [
    "css",
    "scss",
    "sass",
    "less"
  ],
  "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/                                            ]" }
    ]
  },
},

x-prompt 模式

定義原理圖選項的 JSON 模式支持擴展,以允許對提示及其相應(yīng)行為進行聲明式定義。無需其它邏輯或更改原理圖代碼即可支持提示。以下 JSON 模式是 ?x-prompt? 字段的長格式語法的完整描述。

{
    "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

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

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

這將安裝可執(zhí)行文件 ?schematics?,你可以用它在自己的項目文件夾中創(chuàng)建一個新的原理圖集合、把一個新的原理圖添加到一個現(xiàn)有的集合中,或者擴展一個現(xiàn)有的原理圖。

在下面的章節(jié)中,我們將使用 CLI 創(chuàng)建一個新的原理圖集合,以介紹文件和目錄結(jié)構(gòu),以及一些基本概念。

但是,原理圖的最常見用途是將 Angular 庫與 Angular CLI 集成在一起??梢灾苯釉?nbsp;Angular 工作區(qū)的庫項目中創(chuàng)建原理圖文件,而無需使用 Schematics CLI。

創(chuàng)建一個原理圖的集合

下列命令用來在同名的新項目文件夾中創(chuàng)建一個名為 ?hello-world? 的新原理圖。

schematics blank --name=hello-world

?blank ?原理圖是由 Schematics CLI 提供的。該命令用于創(chuàng)建一個新的項目文件夾(該集合的根文件夾),并在該集合中創(chuàng)建一個最初的命名原理圖。

轉(zhuǎn)到 collection 文件夾,安裝你的 npm 依賴,然后在常用的編輯器中打開這個新集合,看看所生成的文件。比如,如果你正在使用 VSCode:

cd hello-world
npm install
npm run build
code .

最初的原理圖與項目文件夾的名字相同,是在 ?src/hello-world? 中生成的。可以把相關(guān)的原理圖添加到這個集合中,并修改所生成的骨架代碼來定義原理圖的功能。每個原理圖的名稱在集合中都必須是唯一的。

運行原理圖

使用 ?schematics ?命令運行一個命名原理圖。按以下格式提供項目文件夾的路徑、原理圖名稱和所有必選項。

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

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

schematics .:hello-world

把原理圖添加到集合中

要把一個原理圖添加到現(xiàn)有的集合中,請使用和新建原理圖項目相同的命令,不過要改為在該項目的文件夾下運行該命令。

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

該命令會在你的集合中生成一個新的命名原理圖,它包含一個主文件 ?index.ts? 及其相關(guān)的測試規(guī)約。它還會把這個新原理圖的名字(name),說明(description)和工廠函數(shù)(factory function)添加到 ?collection.json? 文件中此集合的 JSON 模式中。

集合的內(nèi)容

集合的根文件夾中包含一些配置文件、?node_modules ?文件夾和 ?src/? 文件夾。?src/? 文件夾包含該集合中各個命名原理圖的子文件夾,以及一個模式文件(?collection.json?),它是集合中各個原理圖的模式定義。每個原理圖都是用名稱,描述和工廠函數(shù)創(chuàng)建的。

{
  "$schema":
     "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "hello-world": {
      "description": "A blank schematic.",
      "factory": "./hello-world/index#helloWorld"
    }
  }
}
  • ?$schema? 屬性指定了 CLI 進行驗證時所用的模式。
  • ?schematics ?屬性列出了屬于這個集合的各個命名原理圖。每個原理圖都有一個純文本格式的描述,以及指向主文件中自動生成的那個入口函數(shù)。
  • ?factory ?屬性指向自動生成的那個入口函數(shù)。在這個例子中,你會通過調(diào)用 ?helloWorld()? 工廠函數(shù)來調(diào)用 ?hello-world? 原理圖。
  • 可選屬性 ?schema ?是一個 JSON 模式文件,它定義了本原理圖中可用的命令行參數(shù)。
  • 可選數(shù)組屬性 ?aliases ?指定了一個或多個可用來調(diào)用此原理圖的字符串。比如,Angular CLI “generate” 命令的原理圖有一個別名 “g”,這就可以讓你使用命令 ?ng g?。

命名原理圖

當你使用 Schematics CLI 創(chuàng)建空白原理圖項目時,該集合的第一個成員是一張與該集合同名的空白原理圖。當你把這個新的命名原理圖添加到本集合中時,它會自動添加到 ?collection.json? 模式中。

除了名稱和描述外,每個原理圖還有一個 ?factory ?屬性,用于標識此原理圖的入口點。在本例中,你通過在主文件 ?hello-world/index.ts? 中調(diào)用 ?helloWorld()? 函數(shù)來調(diào)用此原理圖中定義的功能。


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

部分

詳情

index.ts

定義命名原理圖中轉(zhuǎn)換邏輯的代碼。

schema.json

原理圖變量定義。

schema.d.ts

原理圖變量。

files/

要復(fù)制的可選組件/模板文件。

原理圖可以在 ?index.ts? 文件中提供它全部的邏輯,不需要額外的模板。你也可以在 ?files/? 文件夾中提供組件和模板來為 Angular 創(chuàng)建動態(tài)原理圖,比如那些獨立的 Angular 項目。這個 index 文件中的邏輯會通過定義一些用來注入數(shù)據(jù)和修改變量的規(guī)則來配置這些模板。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號