亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在本地開發Angular Schematics

發布時間:2022-02-22 13:46:20 來源:億速云 閱讀:144 作者:iii 欄目:web開發

本文小編為大家詳細介紹“如何在本地開發Angular Schematics”,內容詳細,步驟清晰,細節處理妥當,希望這篇“如何在本地開發Angular Schematics”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

如何在本地開發Angular Schematics

什么是Angular Schematics?

Angular Schematics 是基于模板(Template-based)的,Angular 特有的代碼生成器,當然它不僅僅是生成代碼,也可以修改我們的代碼,它使得我們可以基于 Angular CLI 去實現我們自己的一些自動化操作。

相信在平時開發 Angular 項目的同時,大家都用過 ng generate component component-name, ng add @angular/materials, ng generate module module-name,這些都是 Angular 中已經為我們實現的一些 CLI。

如何在本地開發你的 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

配置 collection.json

之后我們在 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 目錄中加入我們想要插入的文件

關于 template 的語法可以參考 ejs 語法

app.component.html.template

<div class="my-app">
  <% if (defaultLanguage === 'zh-cn') { %>你好,Angular Schematics!<% } else { %>Hello, My First Angular Schematics!<% } %>
  <h2>{{ title }}</h2>
</div>

app.component.scss.template

.app {
  display: flex;
  justify-content: center;
  align-item: center;
}

app.component.ts.template

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = <% if (defaultLanguage === 'zh-cn') { %>'你好'<% } else { %>'Hello'<% } %>;
}

開始實現命令邏輯

  • 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": []
}

在以上的定義中,我們的命令將會接收兩個參數分別為 defaultLanguagei18n,我們以 defaultLanguage 為例講解對參數的相關配置:

{
  "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)"
        }
      ]
    }
  }
}

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 '@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 文件的簡潔,可以將相關操作的方法抽取到一個新的文件中進行引用。

測試 ng-add

至此我們已經完成了 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

讀到這里,這篇“如何在本地開發Angular Schematics”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汽车| 方正县| 宝清县| 天祝| 长春市| 灵川县| 英山县| 饶阳县| 革吉县| 三门峡市| 望城县| 翼城县| 康马县| 佳木斯市| 河西区| 苍山县| 墨竹工卡县| 彩票| 桃源县| 囊谦县| 玉环县| 红安县| 淅川县| 广汉市| 五峰| 乌什县| 行唐县| 汉中市| 隆回县| 巴中市| 修武县| 蓝山县| 怀仁县| 道真| 阳新县| 将乐县| 永宁县| 正阳县| 吉隆县| 赤峰市| 休宁县|