什麼是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
專案。
重要檔案介紹
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 install
。 Rule
:為我們制定的操作邏輯。
實作一個 ng-add 指令
現在我們透過實作一個 ng-add
指令來更好的熟悉。
同樣是基於以上我們已經創建好的專案。
新指令相關的檔案
首先我們在src
目錄下新建一個目錄ng-add
,然後在該目錄下方加入三個檔案index.ts
, schema.json
, schema.ts
,之後你的目錄結構應該如下:
設定<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> 目錄中加入我們想要插入的檔案
關於
<pre class='brush:php;toolbar:false;'><div class="my-app">
<% if (defaultLanguage === &#39;zh-cn&#39;) { %>你好,Angular Schematics!<% } else { %>Hello, My First Angular Schematics!<% } %>
<h1 id="nbsp-title-nbsp">{{ title }}</h1>
</div></pre>
<pre class='brush:php;toolbar:false;'>.app {
display: flex;
justify-content: center;
align-item: center;
}</pre>
<pre class='brush:php;toolbar:false;'>import { Component } from &#39;@angular/core&#39;;
@Component({
selector: &#39;app-root&#39;,
templateUrl: &#39;./app.component.html&#39;,
styleUrls: [&#39;./app.component.scss&#39;]
})
export class AppComponent {
title = <% if (defaultLanguage === &#39;zh-cn&#39;) { %>&#39;你好&#39;<% } else { %>&#39;Hello&#39;<% } %>;
}</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": [] }
在以上的定義中,我們的指令將會接收兩個參數分別為
,i18n
,我們以 defaultLanguage
為例講解對參數的相關配置:<pre class='brush:php;toolbar:false;'>{
"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)"
}
]
}
}
}</pre><p><code>type
代表该参数的类型是 string
。default
为该参数的默认值为 zh-cn
。x-prompt
定义与用户的交互,message
为我们对用户进行的相关提问,在这里我们的 type
为 list
代表我们会为用户提供 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 '@angular-devkit/schematics'; import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { Schema as AddOptions } from './schema'; let projectWorkspace: { root: string; sourceRoot: string; defaultProject: string; }; export type packgeType = 'dependencies' | 'devDependencies' | 'scripts'; export const PACKAGES_I18N = [ '@devui-design/icons@^1.2.0', '@ngx-translate/core@^13.0.0', '@ngx-translate/http-loader@^6.0.0', 'ng-devui@^11.1.0' ]; export const PACKAGES = ['@devui-design/icons@^1.2.0', 'ng-devui@^11.1.0']; export const PACKAGE_JSON_PATH = 'package.json'; export const ANGULAR_JSON_PATH = 'angular.json'; 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, 'dependencies'); // 执行 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( 'Please make sure the project is an Angular project.' ); } let defaultProject = angularJSON.defaultProject; projectWorkspace = { root: '/', 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('./files'), [ 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('utf-8'); 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 = 'dependencies' ): Tree { const packageJson = readPackageJson(tree, type); if (packageJson == null) { return tree; } if (!Array.isArray(packages)) { packages = [packages]; } packages.forEach((pck) => { const splitPosition = pck.lastIndexOf('@'); 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 文件夹,将图中标蓝的文件拷贝到其中
- 之后在命令行中执行
npm link libs/
- link 完成之后
cd libs && npm run build && cd ..
- 现在执行
ng add first-schematics
之后会看到如下提示
- 最后我们通过
npm start
来查看执行的结果如下
结语
综上简单介绍了一个 Schematics
的实现,更多的一些应用欢迎大家查看 ng-devui-admin 中的实现。
更多编程相关知识,请访问:编程学习!!
以上是什麼是Angular Schematics?如何搭建? (詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

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

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

記事本++7.3.1
好用且免費的程式碼編輯器

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