搜尋
首頁web前端js教程什麼是Angular Schematics?如何搭建? (詳解)

什麼是Angular Schematics?如何在本地開發你的 Angular Schematics?以下這篇文章就來給大家詳細介紹一下,並透過一個例子來更好的熟悉,希望對大家有幫助!

什麼是Angular Schematics?如何搭建? (詳解)

什麼是Angular Schematics?

Angular Schematics 是基於模板(Template-based)的,Angular 特有的程式碼產生器,當然它不只是產生程式碼,也可以修改我們的程式碼,它使得我們可以基於Angular CLI 去實作我們自己的一些自動化操作。 【相關教學推薦:《angular教學》】

相信在平常開發Angular 專案的同時,大家都用過ng generate component component-name, ng add @angular/materials, ng generate module module-name,這些都是Angular 中已經為我們實現的一些CLI,那麼我們應該如何在自己的專案中去實現基於自己專案的CLI 呢?本文將會基於我們在 ng-devui-admin 中的實踐來進行介紹。歡迎大家持續的關注,後續我們將會推出更豐富的 CLI 幫助大家更快搭建一個 Admin 頁面。

如何在本地開發你的Angular Schematics

在本地開發你需要先安裝schematics 腳手架

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

# 安装完成之后新建一个schematics项目
schematics blank --name=your-schematics

新建專案之後你會看到如下目錄結構,代表你已經成功創建一個shematics 專案。

什麼是Angular Schematics?如何搭建? (詳解)

重要檔案介紹

  • tsconfig.json: 主要與專案打包編譯相關,在這不做具體介紹

  • collection.json:與你的CLI 指令相關,用來定義你的相關指令

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

first-schematics: 指令的名字,可以在專案中透過ng g first-schematics:first-schematics 來執行該指令。 description: 對該條指令的描述。 factory: 指令執行的入口函數 通常還會有另一個屬性 schema,我們會在後面講解。

  • index.ts:在該檔案中實作你指令的相關邏輯
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';

export function firstSchematics(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    return tree;
  };
}

在這裡我們先看幾個需要了解的參數:tree:在這裡你可以將tree 理解為我們整個的angular 項目,你可以透過tree 新增文件,修改文件,以及刪除文件。 _context:此參數為 schematics 運行的上下文,例如你可以透過 context 執行 npm installRule:為我們制定的操作邏輯。

實作一個 ng-add 指令

現在我們透過實作一個 ng-add 指令來更好的熟悉。

同樣是基於以上我們已經創建好的專案。

新指令相關的檔案

首先我們在src 目錄下新建一個目錄ng-add ,然後在該目錄下方加入三個檔案index.ts, schema.json, schema.ts,之後你的目錄結構應該如下:

什麼是Angular Schematics?如何搭建? (詳解)

設定<span style="font-size: 18px;">#collection.json</span>

##之後我們在

collection.json 中配置該條指令:

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    ...,
    "ng-add": {
      "factory": "./ng-add/index",
      "description": "Some description about your schematics",
      "schema": "./ng-add/schema.json"
    }
  }
}

#在##files<span style="font-size: 18px;"></span> 目錄中加入我們想要插入的檔案關於

template

的語法可以參考ejs 語法

app.component.html.template

<pre class='brush:php;toolbar:false;'>&lt;div class=&quot;my-app&quot;&gt; &lt;% if (defaultLanguage === &amp;#39;zh-cn&amp;#39;) { %&gt;你好,Angular Schematics!&lt;% } else { %&gt;Hello, My First Angular Schematics!&lt;% } %&gt; &lt;h1 id=&quot;nbsp-title-nbsp&quot;&gt;{{ title }}&lt;/h1&gt; &lt;/div&gt;</pre>

app.component.scss.template

<pre class='brush:php;toolbar:false;'>.app { display: flex; justify-content: center; align-item: center; }</pre>

app.component.ts.template

<pre class='brush:php;toolbar:false;'>import { Component } from &amp;#39;@angular/core&amp;#39;; @Component({ selector: &amp;#39;app-root&amp;#39;, templateUrl: &amp;#39;./app.component.html&amp;#39;, styleUrls: [&amp;#39;./app.component.scss&amp;#39;] }) export class AppComponent { title = &lt;% if (defaultLanguage === &amp;#39;zh-cn&amp;#39;) { %&gt;&amp;#39;你好&amp;#39;&lt;% } else { %&gt;&amp;#39;Hello&amp;#39;&lt;% } %&gt;; }</pre>

開始實作指令邏輯

    #schema.json
  • :在該檔案中定義與用戶的互動
    {
      "$schema": "http://json-schema.org/schema",
      "id": "SchematicsDevUI",
      "title": "DevUI Options Schema",
      "type": "object",
      "properties": {
        "defaultLanguage": {
          "type": "string",
          "description": "Choose the default language",
          "default": "zh-cn",
          "x-prompt": {
            "message": "Please choose the default language you want to use: ",
            "type": "list",
            "items": [
              {
                "value": "zh-cn",
                "label": "简体中文 (zh-ch)"
              },
              {
                "value": "en-us",
                "label": "English (en-us)"
              }
            ]
          }
        },
        "i18n": {
          "type": "boolean",
          "default": true,
          "description": "Config i18n for the project",
          "x-prompt": "Would you like to add i18n? (default: Y)"
        }
      },
      "required": []
    }
  • 在以上的定義中,我們的指令將會接收兩個參數分別為
defaultLanguage

i18n,我們以 defaultLanguage 為例講解對參數的相關配置:<pre class='brush:php;toolbar:false;'>{ &quot;defaultLanguage&quot;: { &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Choose the default language&quot;, &quot;default&quot;: &quot;zh-cn&quot;, &quot;x-prompt&quot;: { &quot;message&quot;: &quot;Please choose the default language you want to use: &quot;, &quot;type&quot;: &quot;list&quot;, &quot;items&quot;: [ { &quot;value&quot;: &quot;zh-cn&quot;, &quot;label&quot;: &quot;简体中文 (zh-ch)&quot; }, { &quot;value&quot;: &quot;en-us&quot;, &quot;label&quot;: &quot;English (en-us)&quot; } ] } } }</pre><p><code>type 代表该参数的类型是 stringdefault 为该参数的默认值为 zh-cnx-prompt 定义与用户的交互,message 为我们对用户进行的相关提问,在这里我们的 typelist 代表我们会为用户提供 items 中列出的选项供用户进行选择。

  • schema.ts:在该文件中定义我们接收到的参数类型
export interface Schema {
  defaultLanguage: string;
  i18n: boolean;
}
  • index.ts:在该文件中实现我们的操作逻辑,假设在此次 ng-add 操作中,我们根据用户输入的 defaultLanguage, i18n 来对用户的项目进行相应的更改,并且插入相关的 npm 包,再进行安装。
import {
  apply,
  applyTemplates,
  chain,
  mergeWith,
  move,
  Rule,
  SchematicContext,
  SchematicsException,
  Tree,
  url
} from &#39;@angular-devkit/schematics&#39;;
import { NodePackageInstallTask } from &#39;@angular-devkit/schematics/tasks&#39;;
import { Schema as AddOptions } from &#39;./schema&#39;;

let projectWorkspace: {
  root: string;
  sourceRoot: string;
  defaultProject: string;
};

export type packgeType = &#39;dependencies&#39; | &#39;devDependencies&#39; | &#39;scripts&#39;;
export const PACKAGES_I18N = [
  &#39;@devui-design/icons@^1.2.0&#39;,
  &#39;@ngx-translate/core@^13.0.0&#39;,
  &#39;@ngx-translate/http-loader@^6.0.0&#39;,
  &#39;ng-devui@^11.1.0&#39;
];
export const PACKAGES = [&#39;@devui-design/icons@^1.2.0&#39;, &#39;ng-devui@^11.1.0&#39;];
export const PACKAGE_JSON_PATH = &#39;package.json&#39;;
export const ANGULAR_JSON_PATH = &#39;angular.json&#39;;

export default function (options: AddOptions): Rule {
  return (tree: Tree, context: SchematicContext) => {
    // 获取项目空间中我们需要的相关变量
    getWorkSpace(tree);

    // 根据是否选择i18n插入不同的packages
    const packages = options.i18n ? PACKAGES_I18N : PACKAGES;
    addPackage(tree, packages, &#39;dependencies&#39;);

    // 执行 npm install
    context.addTask(new NodePackageInstallTask());

    // 自定义的一系列 Rules
    return chain([removeOriginalFiles(), addSourceFiles(options)]);
  };
}

下面时使用到的函数的具体实现:

// getWorkSpace
function getWorkSpace(tree: Tree) {
  let angularJSON;
  let buffer = tree.read(ANGULAR_JSON_PATH);
  if (buffer) {
    angularJSON = JSON.parse(buffer.toString());
  } else {
    throw new SchematicsException(
      &#39;Please make sure the project is an Angular project.&#39;
    );
  }

  let defaultProject = angularJSON.defaultProject;
  projectWorkspace = {
    root: &#39;/&#39;,
    sourceRoot: angularJSON.projects[defaultProject].sourceRoot,
    defaultProject
  };

  return projectWorkspace;
}
// removeOriginalFiles
// 根据自己的需要选择需要删除的文件
function removeOriginalFiles() {
  return (tree: Tree) => {
    [
      `${projectWorkspace.sourceRoot}/app/app.component.ts`,
      `${projectWorkspace.sourceRoot}/app/app.component.html`,
      `${projectWorkspace.sourceRoot}/app/app.component.scss`,
      `${projectWorkspace.sourceRoot}/app/app.component.css`
    ]
      .filter((f) => tree.exists(f))
      .forEach((f) => tree.delete(f));
  };
}

将 files 下的文件拷贝到指定的路径下,关于 chain, mergeWith, apply, template 的详细使用方法可以参考 Schematics

// addSourceFiles
function addSourceFiles(options: AddOptions): Rule {
  return chain([
    mergeWith(
      apply(url(&#39;./files&#39;), [
        applyTemplates({
          defaultLanguage: options.defaultLanguage
        }),
        move(`${projectWorkspace.sourceRoot}/app`)
      ])
    )
  ]);
}
// readJson
function readJson(tree: Tree, file: string, type?: string): any {
  if (!tree.exists(file)) {
    return null;
  }

  const sourceFile = tree.read(file)!.toString(&#39;utf-8&#39;);
  try {
    const json = JSON.parse(sourceFile);
    if (type && !json[type]) {
      json[type] = {};
    }
    return json;
  } catch (error) {
    console.log(`Failed when parsing file ${file}.`);
    throw error;
  }
}

// writeJson
export function writeJson(tree: Tree, file: string, source: any): void {
  tree.overwrite(file, JSON.stringify(source, null, 2));
}

// readPackageJson
function readPackageJson(tree: Tree, type?: string): any {
  return readJson(tree, PACKAGE_JSON_PATH, type);
}

// writePackageJson
function writePackageJson(tree: Tree, json: any): any {
  return writeJson(tree, PACKAGE_JSON_PATH, json);
}

// addPackage
function addPackage(
  tree: Tree,
  packages: string | string[],
  type: packgeType = &#39;dependencies&#39;
): Tree {
  const packageJson = readPackageJson(tree, type);

  if (packageJson == null) {
    return tree;
  }

  if (!Array.isArray(packages)) {
    packages = [packages];
  }
  packages.forEach((pck) => {
    const splitPosition = pck.lastIndexOf(&#39;@&#39;);
    packageJson[type][pck.substr(0, splitPosition)] = pck.substr(
      splitPosition + 1
    );
  });

  writePackageJson(tree, packageJson);
  return tree;
}

为了保持 index.ts 文件的简洁,可以将相关操作的方法抽取到一个新的文件中进行引用。

测试 <span style="font-size: 18px;">ng-add</span>

至此我们已经完成了 ng-add 命令,现在我们对该命令进行测试:

  • ng new test 初始化一个 Angular 项目
  • cd test && mkdir libs 在项目中添加一个 libs 文件夹,将图中标蓝的文件拷贝到其中

什麼是Angular Schematics?如何搭建? (詳解)

  • 之后在命令行中执行 npm link libs/
  • link 完成之后 cd libs && npm run build && cd ..
  • 现在执行 ng add first-schematics 之后会看到如下提示

什麼是Angular Schematics?如何搭建? (詳解)

  • 最后我们通过 npm start 来查看执行的结果如下

什麼是Angular Schematics?如何搭建? (詳解)

结语

综上简单介绍了一个 Schematics 的实现,更多的一些应用欢迎大家查看 ng-devui-admin 中的实现。

更多编程相关知识,请访问:编程学习!!

以上是什麼是Angular Schematics?如何搭建? (詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
聊聊Angular中的元数据(Metadata)和装饰器(Decorator)聊聊Angular中的元数据(Metadata)和装饰器(Decorator)Feb 28, 2022 am 11:10 AM

本篇文章继续Angular的学习,带大家了解一下Angular中的元数据和装饰器,简单了解一下他们的用法,希望对大家有所帮助!

angular学习之详解状态管理器NgRxangular学习之详解状态管理器NgRxMay 25, 2022 am 11:01 AM

本篇文章带大家深入了解一下angular的状态管理器NgRx,介绍一下NgRx的使用方法,希望对大家有所帮助!

浅析angular中怎么使用monaco-editor浅析angular中怎么使用monaco-editorOct 17, 2022 pm 08:04 PM

angular中怎么使用monaco-editor?下面本篇文章记录下最近的一次业务中用到的 monaco-editor 在 angular 中的使用,希望对大家有所帮助!

Angular + NG-ZORRO快速开发一个后台系统Angular + NG-ZORRO快速开发一个后台系统Apr 21, 2022 am 10:45 AM

本篇文章给大家分享一个Angular实战,了解一下angualr 结合 ng-zorro 如何快速开发一个后台系统,希望对大家有所帮助!

项目过大怎么办?如何合理拆分Angular项目?项目过大怎么办?如何合理拆分Angular项目?Jul 26, 2022 pm 07:18 PM

Angular项目过大,怎么合理拆分它?下面本篇文章给大家介绍一下合理拆分Angular项目的方法,希望对大家有所帮助!

聊聊自定义angular-datetime-picker格式的方法聊聊自定义angular-datetime-picker格式的方法Sep 08, 2022 pm 08:29 PM

怎么自定义angular-datetime-picker格式?下面本篇文章聊聊自定义格式的方法,希望对大家有所帮助!

浅析Angular中的独立组件,看看怎么使用浅析Angular中的独立组件,看看怎么使用Jun 23, 2022 pm 03:49 PM

本篇文章带大家了解一下Angular中的独立组件,看看怎么在Angular中创建一个独立组件,怎么在独立组件中导入已有的模块,希望对大家有所帮助!

聊聊Angular Route中怎么提前获取数据聊聊Angular Route中怎么提前获取数据Jul 13, 2022 pm 08:00 PM

Angular Route中怎么提前获取数据?下面本篇文章给大家介绍一下从 Angular Route 中提前获取数据的方法,希望对大家有所帮助!

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中