iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 28
0
Modern Web

高效 Coding 術:Angular Schematics 實戰三十天系列 第 28

[高效 Coding 術:Angular Schematics 實戰三十天] Day27 - Angular Schematics API List (四)

此篇介紹的大多都是資料介面、資料模型的定義,不過還是有部分是很好用的 API ,依序為:

  • change
    • Host
    • Change
    • NoopChange
    • InsertChange
    • RemoveChange
    • ReplaceChange
  • workspace
    • updateWorkspace
    • getWorkspace ( async
    • buildDefaultPath
    • createDefaultPath ( async
  • lint-fix
    • applyLintFix
  • test/get-file-content
    • getFileContent
  • test/create-app-module
    • createAppModule
  • workspace-models
    • ProjectType
    • Builders
    • FileReplacements
    • BrowserBuilderBaseOptions
    • BrowserBuilderOptions
    • ServeBuilderOptions
    • LibraryBuilderOptions
    • ServerBuilderOptions
    • AppShellBuilderOptions
    • TestBuilderOptions
    • LintBuilderOptions
    • ExtractI18nOptions
    • E2EOptions
    • BuilderTarget
    • XXXXXXBuilderTarget
    • WorkspaceSchema
    • WorkspaceProject
    • WorkspaceTargets
  • latest-versions
    • latestVersions

change

change 主要是定義有變動時,其所需要的資料介面與資料模型

引入路徑:

import { 
  Host,
  Change,
  NoopChange,
  InsertChange,
  RemoveChange,
  ReplaceChange
} from '@schematics/angular/utility/change';

Host

用途:定義 Changeapply 方法會使用的資料介面。

程式碼:

interface Host {
  write(path: string, content: string): Promise<void>;
  read(path: string): Promise<string>;
}

原始碼

Change

用途:定義變動時,所需資料的資料介面。

程式碼:

interface Change {
  apply(host: Host): Promise<void>;
  readonly path: string | null; // 欲變動之檔案的路徑(含檔名)
  readonly order: number;       // 發生變動的位置
  readonly description: string; // 此變動之敘述
}

原始碼

NoopChange

用途:定義沒有任何變動時的資料模型。

程式碼:

class NoopChange implements Change {
  description = 'No operation.';
  order = Infinity;
  path = null;
  apply() { return Promise.resolve(); }
}

原始碼

InsertChange

用途:定義有新增的變動時的資料模型。

程式碼:

class InsertChange implements Change {
  order: number;
  description: string;

  constructor(public path: string, public pos: number, public toAdd: string) {
    if (pos < 0) {
      throw new Error('Negative positions are invalid');
    }
    this.description = `Inserted ${toAdd} into position ${pos} of ${path}`;
    this.order = pos;
  }

  apply(host: Host) {
    return host.read(this.path).then(content => {
      const prefix = content.substring(0, this.pos);
      const suffix = content.substring(this.pos);

      return host.write(this.path, `${prefix}${this.toAdd}${suffix}`);
    });
  }
}

原始碼

RemoveChange

用途:定義有移除的變動時的資料模型。

程式碼:

class RemoveChange implements Change {
  order: number;
  description: string;

  constructor(public path: string, private pos: number, private toRemove: string) {
    if (pos < 0) {
      throw new Error('Negative positions are invalid');
    }
    this.description = `Removed ${toRemove} into position ${pos} of ${path}`;
    this.order = pos;
  }

  apply(host: Host): Promise<void> {
    return host.read(this.path).then(content => {
      const prefix = content.substring(0, this.pos);
      const suffix = content.substring(this.pos + this.toRemove.length);
      
      return host.write(this.path, `${prefix}${suffix}`);
    });
  }
}

原始碼

ReplaceChange

用途:定義有取代的變動時的資料模型。

程式碼:

class ReplaceChange implements Change {
  order: number;
  description: string;

  constructor(public path: string, private pos: number, private oldText: string,
              private newText: string) {
    if (pos < 0) {
      throw new Error('Negative positions are invalid');
    }
    this.description = `Replaced ${oldText} into position ${pos} of ${path} with ${newText}`;
    this.order = pos;
  }

  apply(host: Host): Promise<void> {
    return host.read(this.path).then(content => {
      const prefix = content.substring(0, this.pos);
      const suffix = content.substring(this.pos + this.oldText.length);
      const text = content.substring(this.pos, this.pos + this.oldText.length);

      if (text !== this.oldText) {
        return Promise.reject(new Error(`Invalid replace: "${text}" != "${this.oldText}".`));
      }

      return host.write(this.path, `${prefix}${this.newText}${suffix}`);
    });
  }
}

原始碼


workspace

change 主要是定義有變動時,其所需要的資料介面與資料模型

引入路徑:

import { 
  updateWorkspace,
  getWorkspace,
  buildDefaultPath,
  createDefaultPath
} from '@schematics/angular/utility/workspace';

updateWorkspace

用途:根據傳入的 angular.json 或是 .angular.json 的配置 來更新 angular.json 或是 .angular.json 的配置。

回傳值: Rule 。

用法:

const workspace = await getWorkspace(tree);

updateWorkspace(workspace)

原始碼

getWorkspace ( async

用途:取得 angular.json 或是 .angular.json 的配置。

回傳值: angular.json 或是 .angular.json 的配置 。

用法:

await getWorkspace(tree);

原始碼

buildDefaultPath

用途:根據傳入的應用或函式庫的配置來取得預設的路徑。

回傳值:應用或函式庫的預設路徑 。

用法:

const workspace = await getWorkspace(tree);
const project = workspace.projects.get('hello-world');

buildDefaultPath(project); // defaul project will equal to '/src/app'

原始碼

createDefaultPath ( async

用途:根據傳入的檔案樹應用配置來取得預設的路徑。

回傳值:應用或函式庫的預設路徑 。

用法:

createDefaultPath(tree, 'hello-world'); // defaul project will equal to '/src/app'

原始碼


lint-fix

只有一個用來修正 tslint.json 或是 tslint.yaml 的 API 。

引入路徑:

import { applyLintFix } from '@schematics/angular/utility/lint-fix';

applyLintFix

用途:修正傳入的檔案路徑內的 tslint.json 或是 tslint.yaml 檔名開頭的 /

回傳值: Rule 。

用法:

applyLintFix();

原始碼


test/get-file-content

只有一個用來取得檔案內容的函式

引入路徑:

import { getFileContent } from '@schematics/angular/utility/test/get-file-content';

getFileContent

用途:根據傳入的檔案樹檔案路徑(含檔名)來取得檔案的內容。

回傳值: 檔案的內容(字串) 。

用法:

getFileContent(tree, '/src/app/app.module.ts');

原始碼


test/create-app-module

只有一個用來創造 AppModule 檔案內容的函式,而且只能給測試用。

引入路徑:

import { createAppModule } from '@schematics/angular/utility/test/create-app-module';

getFileContent

用途:根據傳入的測試用的檔案樹檔案路徑(含檔名,非必填)來創造一個檔案內容跟 AppModule 一樣的檔案(因資料類型的關係,只能用在測試裡)。

回傳值: 測試用的檔案樹。

用法:

createAppModule(tree);

原始碼


workspace-models

workspace-models 都是定義一些專案、應用與編譯的配置的資料介面、資料模型、某些類型的別名。

引入路徑:

import { 
  ProjectType,
  Builders,
  FileReplacements,
  BrowserBuilderBaseOptions,
  BrowserBuilderOptions,
  ServeBuilderOptions,
  LibraryBuilderOptions,
  ServerBuilderOptions,
  AppShellBuilderOptions,
  TestBuilderOptions,
  LintBuilderOptions,
  ExtractI18nOptions,
  E2EOptions,
  BuilderTarget,
  LibraryBuilderTarget,
  BrowserBuilderTarget,
  ServerBuilderTarget,
  AppShellBuilderTarget,
  LintBuilderTarget,
  TestBuilderTarget,
  ServeBuilderTarget,
  ExtractI18nBuilderTarget,
  E2EBuilderTarget,
  WorkspaceSchema,
  WorkspaceProject,
  WorkspaceTargets
} from '@schematics/angular/utility/change';

ProjectType

用途:定義所有應用型別的列舉。

程式碼:

enum ProjectType {
    Application = 'application',
    Library = 'library',
}

原始碼

Builders

用途:定義所有編譯器指令的列舉。

程式碼:

enum Builders {
    AppShell = '@angular-devkit/build-angular:app-shell',
    Server = '@angular-devkit/build-angular:server',
    Browser = '@angular-devkit/build-angular:browser',
    Karma = '@angular-devkit/build-angular:karma',
    TsLint = '@angular-devkit/build-angular:tslint',
    NgPackagr = '@angular-devkit/build-ng-packagr:build',
    DevServer = '@angular-devkit/build-angular:dev-server',
    ExtractI18n = '@angular-devkit/build-angular:extract-i18n',
    Protractor = '@angular-devkit/build-angular:protractor',
}

原始碼

FileReplacements

用途:定義實作 FileReplacements 時所需資料的資料介面。

程式碼:

interface FileReplacements {
    replace: string;
    with: string;
}

原始碼

BrowserBuilderBaseOptions

用途:定義編譯器配置基本會有的資料介面。

程式碼:

interface BrowserBuilderBaseOptions {
    main: string;
    tsConfig: string;
    fileReplacements?: FileReplacements[];
    outputPath?: string;
    index?: string;
    polyfills: string;
    assets?: (object|string)[];
    styles?: (object|string)[];
    scripts?: (object|string)[];
    sourceMap?: boolean;
}

原始碼

BrowserBuilderOptions

用途:定義一般的編譯器配置的資料介面。

程式碼:

interface BrowserBuilderOptions extends BrowserBuilderBaseOptions {
    serviceWorker?: boolean;
    optimization?: boolean;
    outputHashing?: 'all';
    resourcesOutputPath?: string;
    extractCss?: boolean;
    namedChunks?: boolean;
    aot?: boolean;
    extractLicenses?: boolean;
    vendorChunk?: boolean;
    buildOptimizer?: boolean;
    ngswConfigPath?: string;
    budgets?: {
        type: string;
        maximumWarning?: string;
        maximumError?: string;
    }[];
    es5BrowserSupport?: boolean;
    webWorkerTsConfig?: string;
}

原始碼

ServeBuilderOptions

用途:定義服務的編譯器配置的資料介面。

程式碼:

interface ServeBuilderOptions {
    browserTarget: string;
}

原始碼

LibraryBuilderOptions

用途:定義函式庫的編譯器配置的資料介面。

程式碼:

interface LibraryBuilderOptions {
    tsConfig: string;
    project: string;
}

原始碼

ServerBuilderOptions

用途:定義伺服器的編譯器配置的資料介面。

程式碼:

interface ServerBuilderOptions {
    outputPath: string;
    tsConfig: string;
    main: string;
    fileReplacements?: FileReplacements[];
    optimization?: {
        scripts?: boolean;
        styles?: boolean;
    };
    sourceMap?: boolean;
}

原始碼

AppShellBuilderOptions

用途:定義應用程式外殼的編譯器配置的資料介面。

程式碼:

interface AppShellBuilderOptions {
    browserTarget: string;
    serverTarget: string;
    route: string;
}

原始碼

TestBuilderOptions

用途:定義測試的編譯器配置的資料介面。

程式碼:

interface TestBuilderOptions extends Partial<BrowserBuilderBaseOptions> {
    karmaConfig: string;
}

原始碼

LintBuilderOptions

用途:定義 Lint 的編譯器配置的資料介面。

程式碼:

interface LintBuilderOptions {
    tsConfig: string[] | string;
    exclude?: string[];
}

原始碼

ExtractI18nOptions

用途:定義多國語系的編譯器配置的資料介面。

程式碼:

interface ExtractI18nOptions {
    browserTarget: string;
}

原始碼

E2EOptions

用途:定義 End-to-End 的編譯器配置的資料介面。

程式碼:

interface E2EOptions {
    protractorConfig: string;
    devServerTarget: string;
}

原始碼

BuilderTarget

用途:定義編譯器目標基本會有的資料介面。

程式碼:

interface BuilderTarget<TBuilder extends Builders, TOptions> {
    builder: TBuilder;
    options: TOptions;
    configurations?: {
        production: Partial<TOptions>;
        [key: string]: Partial<TOptions>;
    };
}

原始碼

XXXXXXBuilderTarget

用途:替使用於不同的編譯器指令不同的編譯器配置的編譯器目標取別名。

程式碼:

type LibraryBuilderTarget = BuilderTarget<Builders.NgPackagr, LibraryBuilderOptions>;
type BrowserBuilderTarget = BuilderTarget<Builders.Browser, BrowserBuilderOptions>;
type ServerBuilderTarget = BuilderTarget<Builders.Server, ServerBuilderOptions>;
type AppShellBuilderTarget = BuilderTarget<Builders.AppShell, AppShellBuilderOptions>;
type LintBuilderTarget = BuilderTarget<Builders.TsLint, LintBuilderOptions>;
type TestBuilderTarget = BuilderTarget<Builders.Karma, TestBuilderOptions>;
type ServeBuilderTarget = BuilderTarget<Builders.DevServer, ServeBuilderOptions>;
type ExtractI18nBuilderTarget = BuilderTarget<Builders.ExtractI18n, ExtractI18nOptions>;
type E2EBuilderTarget = BuilderTarget<Builders.Protractor, E2EOptions>;

原始碼

WorkspaceSchema

用途:定義專案配置會有的資料介面。

程式碼:

interface WorkspaceSchema extends experimental.workspace.WorkspaceSchema {
    projects: {
        [key: string]: WorkspaceProject<ProjectType.Application | ProjectType.Library>;
    };
}

原始碼

WorkspaceProject

用途:定義應用配置會有的資料介面。

程式碼:

interface WorkspaceProject<TProjectType extends ProjectType = ProjectType.Application>
    extends experimental.workspace.WorkspaceProject {
    projectType: ProjectType;
    architect?: WorkspaceTargets<TProjectType>;
    targets?: WorkspaceTargets<TProjectType>;
}

原始碼

WorkspaceTargets

用途:定義應用的編譯配置會有的資料介面。

程式碼:

interface WorkspaceTargets<TProjectType extends ProjectType = ProjectType.Application> {
    build?: TProjectType extends ProjectType.Library ? LibraryBuilderTarget : BrowserBuilderTarget;
    server?: ServerBuilderTarget;
    lint?: LintBuilderTarget;
    test?: TestBuilderTarget;
    serve?: ServeBuilderTarget;
    e2e?: E2EBuilderTarget;
    'app-shell'?: AppShellBuilderTarget;
    'extract-i18n'?: ExtractI18nBuilderTarget;
    [key: string]: any;
}

原始碼


latest-versions

只有一個定義了 Angular 各個核心版本版號的常數。

引入路徑:

import { latestVersions } from '@schematics/angular/utility/latest-versions';

latestVersions

用途:定義了 Angular 各個核心版本版號。

程式碼:

const latestVersions = {
  Angular: '~9.0.0-next.8',
  RxJs: '~6.5.3',
  ZoneJs: '~0.10.2',
  TypeScript: '~3.5.3',
  TsLib: '^1.10.0',
  DevkitBuildAngular: '~0.900.0-next.6',
  DevkitBuildNgPackagr: '~0.900.0-next.6',
  DevkitBuildWebpack: '~0.900.0-next.6',
  AngularPWA: '~0.900.0-next.6',
  ngPackagr: '^5.5.1',
};

原始碼


本日結語

至此,引入路徑在 @schematics/angular/utility 底下的 Angular Schematics API 都全部介紹完畢了!!

雖然本篇所介紹的東西可能會較少用到,但以防大家要用的時候找不到,所以還是全部都列完了!!

本來筆者是想用更好的方式來 Demo 這些 API ,但這些 API 很多是無法單純在前端運作的,只能靠 SSR 來處理。所以之後如果筆者有空,或是有人願意處理的話,應該是可以把這些 API 再整理得更好閱讀一些!

接下來將介紹的是較為核心部分的 API ,敬請期待!

參考資料


上一篇
[高效 Coding 術:Angular Schematics 實戰三十天] Day26 - Angular Schematics API List (三)
下一篇
[高效 Coding 術:Angular Schematics 實戰三十天] Day28 - Angular Schematics API List (五)
系列文
高效 Coding 術:Angular Schematics 實戰三十天32

尚未有邦友留言

立即登入留言