再次关于Angular CLI构建器



你好!我叫Igor,是Tinkoff.ru的前端而且,奇怪的是,我早已无可救药地习惯了Angular及其相关的一切。



Angular: ? React. ng eject: webpack Angular CLI . — webpack.config.js . , Angular CLI v8.0.0 CLI Builders API, , CLI , .



webpack — @angular-builders/custom-webpack. , , , 30 .



? Challenge Accepted!



, Angular Angular CLI, , rxjs , 50 .



?



— , Angular CLI. :



  1. JSON- -
  2. BuilderContext — , , , .


, . Observable. Promise, Observable BuilderOutput.



npm- CLI build, test, lint, deploy architect angular.json.



?



. , . , , NX . , angular.json .



: dev-server . npm- , , dev-server watch- dev-server, ?



?



, . NX, .



npx create-nx-workspace ng-builders
cd ./ng-builders
npx ng g @nrwl/node:library build


semantic-release. CI Github Actions.



, , .





, :



// angular.json
{
  "version": 1,
  "projects": {
    "app": {
      "architect": {
        "stepper": {
          "builder": "@ng-builders/build:stepper",
          "options": {
            "targets": { //  
              "jest": { //     
                "target": "app:jest", //   angular.json  
                "deps": ["server"] //  ,     
              },
              "server": {
                "target": "app:serve",
                "watch": true // watch-
              }
            },
            "steps": ["jest"] //    
          }
        }
      }
    }
  }
}


, angular.json :



ng run app:stepper


:



export interface Target {
  /**
   *  targetId,      
   *
   *   Schema#steps ,      
   *   
   */
  deps?: string[];
  /**
   *   
   */
  target: string;
  /**
   *  watch-
   */
  watch?: boolean;
  /**
   *    
   */
  overrides?: { [key: string]: any };
}

export interface Targets {
  // targetId -  
  [targetId: string]: Target;
}

export interface Schema {
  /**
   *    ,   
   *  targetId  Targets
   *
   *       
   */
  steps: string[];
  targets: Targets;
}


. , , , (production, dev ..), v1.0 .



json-, .



Let's code



, . Angular CLI .



runStepper StepperBuilder.



// index.ts
export function runStepper(
  input: Schema,
  context: BuilderContext
): BuilderOutputLike {
  return buildSteps(input, context).pipe(
    map(() => ({
      success: true
    })),
    catchError(error => {
      return of({ error: error.toString(), success: false });
    })
  );
}

export const StepperBuilder = createBuilder(runStepper);

export default StepperBuilder;


, runStepperSchema . Observable<BuilderOutput> .



buildSteps,



// index.ts
function buildSteps(config: Schema, context: BuilderContext): Observable<any> {
  return concat(
    config.steps.map(step => buildStep(step, config.targets, context))
  );
}


. .



buildStep, :



// index.ts
function buildStep(
  stepName: string,
  targets: Targets,
  context: BuilderContext
): Observable<any> {
  const { deps = [], overrides, target, watch }: Target = targets[stepName];

  const deps$ = deps.length
    ? combineLatest(deps.map(depName => buildStep(depName, targets, context)))
    : of(null);

  return deps$.pipe(
    concatMap(() => {
      return scheduleTargetAndForget(context, targetFromTargetString(target), {
        watch,
        ...overrides
      });
    }),
    watch ? tap(noop) : take(1)
  );
}


:



  1. , — , . , dev-server ( ) ( ).
  2. scheduleTargetAndForget, @angular-devkit/architect. angular.json . Observable, .
  3. watch , , , , Observable, .


, . . 56 . , ?



— builders.json



{
  "$schema": "../../@angular-devkit/architect/src/builders-schema.json",
  "builders": {
    "stepper": {
      "implementation": "./stepper",
      "schema": "./stepper-schema.json",
      "description": "Stepper"
    }
  }
}


, implementation ( ), schema ( ) description ().



package.json builders builders.json



{
    "name": "@ng-builders/build",
    "builders": "./builders.json",
}


:



npm run build


Github.



?



, . , — Angular CLI. , , . , , .



( ) .



npm i @ng-builders/build -D




CLI Builders API — Angular CLI. , , , 1 . ? . , . , !



P.S.:



Angular CLI Builders NX Workspace Angular. . Twitter, Telegram .




All Articles