Hallo! Mein Name ist Igor und ich bin ein Frontend bei Tinkoff.ru. Und seltsamerweise habe ich mich lange und hoffnungslos an Angular und alles, was damit zu tun hat, gewöhnt.
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. :
- JSON- -
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;
, runStepper
— Schema
. 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)
);
}
:
- , — , . , dev-server ( ) ( ).
-
scheduleTargetAndForget
,@angular-devkit/architect
.angular.json
.Observable
, . -
watch
, , , ,Observable
, .
— 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 .