此篇介紹的大多都是資料介面、資料模型的定義,不過還是有部分是很好用的 API ,依序為:
change
主要是定義有變動時,其所需要的資料介面與資料模型
引入路徑:
import {
Host,
Change,
NoopChange,
InsertChange,
RemoveChange,
ReplaceChange
} from '@schematics/angular/utility/change';
用途:定義 Change
的 apply
方法會使用的資料介面。
程式碼:
interface Host {
write(path: string, content: string): Promise<void>;
read(path: string): Promise<string>;
}
用途:定義變動時,所需資料的資料介面。
程式碼:
interface Change {
apply(host: Host): Promise<void>;
readonly path: string | null; // 欲變動之檔案的路徑(含檔名)
readonly order: number; // 發生變動的位置
readonly description: string; // 此變動之敘述
}
用途:定義沒有任何變動時的資料模型。
程式碼:
class NoopChange implements Change {
description = 'No operation.';
order = Infinity;
path = null;
apply() { return Promise.resolve(); }
}
用途:定義有新增的變動時的資料模型。
程式碼:
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}`);
});
}
}
用途:定義有移除的變動時的資料模型。
程式碼:
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}`);
});
}
}
用途:定義有取代的變動時的資料模型。
程式碼:
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}`);
});
}
}
change
主要是定義有變動時,其所需要的資料介面與資料模型
引入路徑:
import {
updateWorkspace,
getWorkspace,
buildDefaultPath,
createDefaultPath
} from '@schematics/angular/utility/workspace';
用途:根據傳入的 angular.json
或是 .angular.json
的配置 來更新 angular.json
或是 .angular.json
的配置。
回傳值: Rule 。
用法:
const workspace = await getWorkspace(tree);
updateWorkspace(workspace)
用途:取得 angular.json
或是 .angular.json
的配置。
回傳值: angular.json
或是 .angular.json
的配置 。
用法:
await getWorkspace(tree);
用途:根據傳入的應用或函式庫的配置來取得預設的路徑。
回傳值:應用或函式庫的預設路徑 。
用法:
const workspace = await getWorkspace(tree);
const project = workspace.projects.get('hello-world');
buildDefaultPath(project); // defaul project will equal to '/src/app'
用途:根據傳入的檔案樹與應用配置來取得預設的路徑。
回傳值:應用或函式庫的預設路徑 。
用法:
createDefaultPath(tree, 'hello-world'); // defaul project will equal to '/src/app'
只有一個用來修正 tslint.json
或是 tslint.yaml
的 API 。
引入路徑:
import { applyLintFix } from '@schematics/angular/utility/lint-fix';
用途:修正傳入的檔案路徑內的 tslint.json
或是 tslint.yaml
檔名開頭的 /
。
回傳值: Rule 。
用法:
applyLintFix();
只有一個用來取得檔案內容的函式
引入路徑:
import { getFileContent } from '@schematics/angular/utility/test/get-file-content';
用途:根據傳入的檔案樹與檔案路徑(含檔名)來取得檔案的內容。
回傳值: 檔案的內容(字串) 。
用法:
getFileContent(tree, '/src/app/app.module.ts');
只有一個用來創造 AppModule
檔案內容的函式,而且只能給測試用。
引入路徑:
import { createAppModule } from '@schematics/angular/utility/test/create-app-module';
用途:根據傳入的測試用的檔案樹與檔案路徑(含檔名,非必填)來創造一個檔案內容跟 AppModule
一樣的檔案(因資料類型的關係,只能用在測試裡)。
回傳值: 測試用的檔案樹。
用法:
createAppModule(tree);
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';
用途:定義所有應用型別的列舉。
程式碼:
enum ProjectType {
Application = 'application',
Library = 'library',
}
用途:定義所有編譯器指令的列舉。
程式碼:
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
時所需資料的資料介面。
程式碼:
interface FileReplacements {
replace: string;
with: string;
}
用途:定義編譯器配置基本會有的資料介面。
程式碼:
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;
}
用途:定義一般的編譯器配置的資料介面。
程式碼:
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;
}
用途:定義服務的編譯器配置的資料介面。
程式碼:
interface ServeBuilderOptions {
browserTarget: string;
}
用途:定義函式庫的編譯器配置的資料介面。
程式碼:
interface LibraryBuilderOptions {
tsConfig: string;
project: string;
}
用途:定義伺服器的編譯器配置的資料介面。
程式碼:
interface ServerBuilderOptions {
outputPath: string;
tsConfig: string;
main: string;
fileReplacements?: FileReplacements[];
optimization?: {
scripts?: boolean;
styles?: boolean;
};
sourceMap?: boolean;
}
用途:定義應用程式外殼的編譯器配置的資料介面。
程式碼:
interface AppShellBuilderOptions {
browserTarget: string;
serverTarget: string;
route: string;
}
用途:定義測試的編譯器配置的資料介面。
程式碼:
interface TestBuilderOptions extends Partial<BrowserBuilderBaseOptions> {
karmaConfig: string;
}
用途:定義 Lint 的編譯器配置的資料介面。
程式碼:
interface LintBuilderOptions {
tsConfig: string[] | string;
exclude?: string[];
}
用途:定義多國語系的編譯器配置的資料介面。
程式碼:
interface ExtractI18nOptions {
browserTarget: string;
}
用途:定義 End-to-End 的編譯器配置的資料介面。
程式碼:
interface E2EOptions {
protractorConfig: string;
devServerTarget: string;
}
用途:定義編譯器目標基本會有的資料介面。
程式碼:
interface BuilderTarget<TBuilder extends Builders, TOptions> {
builder: TBuilder;
options: TOptions;
configurations?: {
production: Partial<TOptions>;
[key: string]: Partial<TOptions>;
};
}
用途:替使用於不同的編譯器指令與不同的編譯器配置的編譯器目標取別名。
程式碼:
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>;
用途:定義專案配置會有的資料介面。
程式碼:
interface WorkspaceSchema extends experimental.workspace.WorkspaceSchema {
projects: {
[key: string]: WorkspaceProject<ProjectType.Application | ProjectType.Library>;
};
}
用途:定義應用配置會有的資料介面。
程式碼:
interface WorkspaceProject<TProjectType extends ProjectType = ProjectType.Application>
extends experimental.workspace.WorkspaceProject {
projectType: ProjectType;
architect?: WorkspaceTargets<TProjectType>;
targets?: WorkspaceTargets<TProjectType>;
}
用途:定義應用的編譯配置會有的資料介面。
程式碼:
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;
}
只有一個定義了 Angular 各個核心版本版號的常數。
引入路徑:
import { latestVersions } from '@schematics/angular/utility/latest-versions';
用途:定義了 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 ,敬請期待!