The Angular CLI provides comprehensive integration with the Angular DevKit Architect system for running build, test, lint, and custom targets. This system enables extensible build pipelines with standardized configuration and execution patterns.
Abstract base class for commands that execute Architect targets with workspace integration and configuration management.
/**
* Base class for commands that run Architect targets
*/
abstract class ArchitectBaseCommandModule extends CommandModule {
/**
* Run a single Architect target
* @param target - Target specifier (project:target:configuration)
* @param options - Target-specific options
* @returns Promise resolving to exit code
*/
protected runSingleTarget(
target: string,
options: Record<string, any>
): Promise<number>;
/**
* Run multiple Architect targets in parallel or sequence
* @param targets - Array of target specifiers
* @param options - Shared options for all targets
* @returns Promise resolving to combined exit code
*/
protected runMultipleTargets(
targets: string[],
options: Record<string, any>
): Promise<number>;
/**
* Get Architect host for workspace operations
* @returns Architect host instance
*/
protected getArchitectHost(): ArchitectHost;
/**
* Get Architect instance for target execution
* @returns Architect instance
*/
protected getArchitect(): Architect;
/**
* Validate target exists and is properly configured
* @param project - Project name
* @param target - Target name
* @returns Promise resolving to validation result
*/
protected validateTarget(
project: string,
target: string
): Promise<TargetValidationResult>;
}Usage Examples:
// Custom build command extending ArchitectBaseCommandModule
class CustomBuildCommand extends ArchitectBaseCommandModule {
async run(options: any) {
// Run build target
const exitCode = await this.runSingleTarget(
'my-app:build:production',
{
outputPath: 'dist/custom',
baseHref: '/app/'
}
);
if (exitCode === 0) {
console.log('Build completed successfully');
}
return exitCode;
}
}Functions for discovering, validating, and executing Architect targets.
/**
* Execute an Architect target
* @param targetSpec - Target specification (project:target:configuration)
* @param options - Target options
* @param workspace - Angular workspace instance
* @returns Promise resolving to execution result
*/
function runArchitectTarget(
targetSpec: string,
options: Record<string, any>,
workspace: AngularWorkspace
): Promise<ArchitectTargetResult>;
/**
* List available targets for a project
* @param project - Project name
* @param workspace - Angular workspace instance
* @returns Array of available target names
*/
function listProjectTargets(
project: string,
workspace: AngularWorkspace
): string[];
/**
* Get target configuration from workspace
* @param project - Project name
* @param target - Target name
* @param workspace - Angular workspace instance
* @returns Target definition or null if not found
*/
function getTargetDefinition(
project: string,
target: string,
workspace: AngularWorkspace
): TargetDefinition | null;
/**
* Validate target configuration
* @param targetDefinition - Target definition to validate
* @returns Validation result with errors if any
*/
function validateTargetDefinition(
targetDefinition: TargetDefinition
): TargetValidationResult;Usage Examples:
import {
runArchitectTarget,
listProjectTargets,
getTargetDefinition,
getWorkspace
} from "@angular/cli";
const workspace = getWorkspace('local');
// List available targets
const targets = listProjectTargets('my-app', workspace);
console.log('Available targets:', targets);
// Get target configuration
const buildTarget = getTargetDefinition('my-app', 'build', workspace);
if (buildTarget) {
console.log(`Builder: ${buildTarget.builder}`);
console.log(`Configurations: ${Object.keys(buildTarget.configurations || {})}`);
}
// Execute target
const result = await runArchitectTarget(
'my-app:build:production',
{
optimization: true,
sourceMap: false
},
workspace
);
console.log(`Target completed with success: ${result.success}`);Standard builders for building Angular applications and libraries.
/**
* Browser application builder options
*/
interface BrowserBuilderOptions {
/** Output path for build artifacts */
outputPath: string;
/** Main application entry point */
main: string;
/** Application index.html file */
index: string;
/** TypeScript configuration file */
tsConfig: string;
/** Polyfills entry point */
polyfills?: string;
/** Global stylesheets */
styles?: (string | StyleElement)[];
/** Global scripts */
scripts?: (string | ScriptElement)[];
/** Assets to copy */
assets?: (string | AssetElement)[];
/** Enable optimization */
optimization?: boolean | OptimizationOptions;
/** Generate source maps */
sourceMap?: boolean | SourceMapOptions;
/** Base href for the application */
baseHref?: string;
/** Deployment URL */
deployUrl?: string;
/** Enable production mode */
prod?: boolean;
}
/**
* Development server builder options
*/
interface DevServerBuilderOptions {
/** Port to listen on */
port?: number;
/** Host to bind to */
host?: string;
/** Open browser automatically */
open?: boolean;
/** Enable HTTPS */
ssl?: boolean;
/** SSL certificate file */
sslCert?: string;
/** SSL private key file */
sslKey?: string;
/** Proxy configuration */
proxyConfig?: string;
/** Public host URL */
publicHost?: string;
/** Disable host check */
disableHostCheck?: boolean;
/** Live reload */
liveReload?: boolean;
/** Hot module replacement */
hmr?: boolean;
}/**
* Library builder options
*/
interface LibraryBuilderOptions {
/** TypeScript configuration file */
tsConfig: string;
/** Project root directory */
project: string;
/** Entry file for the library */
entryFile?: string;
/** UMD module IDs */
umdModuleIds?: Record<string, string>;
/** External dependencies */
external?: string[];
}Builders for running tests and generating coverage reports.
/**
* Karma test builder options
*/
interface KarmaBuilderOptions {
/** Karma configuration file */
karmaConfig?: string;
/** TypeScript configuration */
tsConfig: string;
/** Polyfills entry point */
polyfills?: string;
/** Global styles */
styles?: (string | StyleElement)[];
/** Global scripts */
scripts?: (string | ScriptElement)[];
/** Assets to include */
assets?: (string | AssetElement)[];
/** Generate code coverage */
codeCoverage?: boolean;
/** Coverage directory */
codeCoverageExclude?: string[];
/** Watch mode */
watch?: boolean;
/** Browsers to run tests in */
browsers?: string;
/** Main entry point for tests */
main: string;
}
/**
* Protractor e2e builder options
*/
interface ProtractorBuilderOptions {
/** Protractor configuration file */
protractorConfig: string;
/** Development server target */
devServerTarget?: string;
/** Base URL for tests */
baseUrl?: string;
/** Webdriver update */
webdriverUpdate?: boolean;
}Builder for running ESLint on the project.
/**
* ESLint builder options
*/
interface EslintBuilderOptions {
/** Lint file patterns */
lintFilePatterns: string[];
/** ESLint configuration */
eslintConfig?: string;
/** Exclude patterns */
exclude?: string[];
/** Fix linting errors automatically */
fix?: boolean;
/** Force linting success */
force?: boolean;
/** Quiet mode (only errors) */
quiet?: boolean;
/** Maximum warnings allowed */
maxWarnings?: number;
/** Output format */
format?: string;
}Interface for developing custom Architect builders.
/**
* Builder function signature
*/
type BuilderHandlerFn<T> = (
options: T,
context: BuilderContext
) => Promise<BuilderOutput> | BuilderOutput;
/**
* Builder context provided to builder functions
*/
interface BuilderContext {
/** Builder information */
builder: BuilderInfo;
/** Workspace root */
workspaceRoot: string;
/** Current working directory */
currentDirectory: string;
/** Target being executed */
target?: Target;
/** Logger instance */
logger: logging.LoggerApi;
/** Get target options */
getTargetOptions(target: Target): Promise<JsonObject>;
/** Schedule other targets */
scheduleTarget(target: Target, options?: JsonObject): Promise<BuilderRun>;
/** Validate options against schema */
validateOptions<T extends JsonObject = JsonObject>(
options: JsonObject,
builderName?: string
): Promise<T>;
}
/**
* Builder execution result
*/
interface BuilderOutput {
/** Success status */
success: boolean;
/** Error message if failed */
error?: string;
/** Additional result data */
[key: string]: any;
}import {
BuilderContext,
BuilderOutput,
createBuilder
} from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
interface CustomBuilderOptions extends JsonObject {
command: string;
args: string[];
}
export default createBuilder<CustomBuilderOptions>((options, context) => {
return new Promise<BuilderOutput>((resolve, reject) => {
const { spawn } = require('child_process');
context.logger.info(`Running: ${options.command} ${options.args.join(' ')}`);
const child = spawn(options.command, options.args, {
stdio: 'inherit',
cwd: context.workspaceRoot
});
child.on('close', (code: number) => {
if (code === 0) {
resolve({ success: true });
} else {
resolve({
success: false,
error: `Command failed with exit code ${code}`
});
}
});
child.on('error', (error: Error) => {
reject(error);
});
});
});Targets are configured in the workspace angular.json file:
{
"projects": {
"my-app": {
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/my-app",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json"
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"development": {
"optimization": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
}
}
}
}
}import { getWorkspace } from "@angular/cli";
async function addCustomTarget() {
const workspace = getWorkspace('local');
if (workspace && workspace.projects['my-app']) {
const project = workspace.projects['my-app'];
// Add custom target
project.architect = project.architect || {};
project.architect['custom-deploy'] = {
builder: '@my-company/custom-builders:deploy',
options: {
environment: 'staging',
region: 'us-west-2'
},
configurations: {
production: {
environment: 'production'
}
}
};
// Save workspace
await workspace.save();
}
}import { runArchitectTarget } from "@angular/cli";
async function buildAllProjects() {
const workspace = getWorkspace('local');
const projectNames = Object.keys(workspace.projects);
// Run builds in parallel
const buildPromises = projectNames.map(project =>
runArchitectTarget(`${project}:build:production`, {}, workspace)
);
const results = await Promise.all(buildPromises);
const allSuccessful = results.every(result => result.success);
console.log(`All builds successful: ${allSuccessful}`);
return allSuccessful ? 0 : 1;
}import { runArchitectTarget } from "@angular/cli";
async function deployWorkflow() {
const workspace = getWorkspace('local');
// Sequential execution: build -> test -> deploy
const buildResult = await runArchitectTarget(
'my-app:build:production', {}, workspace
);
if (!buildResult.success) {
throw new Error('Build failed');
}
const testResult = await runArchitectTarget(
'my-app:test', { watch: false }, workspace
);
if (!testResult.success) {
throw new Error('Tests failed');
}
const deployResult = await runArchitectTarget(
'my-app:deploy:production', {}, workspace
);
return deployResult;
}/**
* Target definition in workspace configuration
*/
interface TargetDefinition {
/** Builder to use for this target */
builder: string;
/** Default options */
options?: JsonObject;
/** Named configurations */
configurations?: Record<string, JsonObject>;
/** Default configuration name */
defaultConfiguration?: string;
}
/**
* Target execution result
*/
interface ArchitectTargetResult {
/** Execution success status */
success: boolean;
/** Error information if failed */
error?: string;
/** Builder output data */
result?: JsonObject;
}
/**
* Target validation result
*/
interface TargetValidationResult {
/** Validation success status */
isValid: boolean;
/** Validation error messages */
errors: string[];
/** Warning messages */
warnings: string[];
}
/**
* Asset configuration element
*/
interface AssetElement {
/** Source glob pattern */
glob: string;
/** Input directory */
input: string;
/** Output directory */
output: string;
/** Ignore patterns */
ignore?: string[];
}
/**
* Style configuration element
*/
interface StyleElement {
/** Input file path */
input: string;
/** Bundle name */
bundleName?: string;
/** Inject into index.html */
inject?: boolean;
}
/**
* Script configuration element
*/
interface ScriptElement {
/** Input file path */
input: string;
/** Bundle name */
bundleName?: string;
/** Inject into index.html */
inject?: boolean;
/** Lazy load */
lazy?: boolean;
}