Skip to content

Commit

Permalink
feat(@angular-devkit/build-angular): add ng-packagr builder in `@an…
Browse files Browse the repository at this point in the history
…gular-devkit/build-angular`

With this change we add the `ng-packagr` builder in `@angular-devkit/build-angular`
  • Loading branch information
alan-agius4 committed Aug 14, 2020
1 parent ba7f6e8 commit e5b29ac
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 5 deletions.
8 changes: 8 additions & 0 deletions packages/angular_devkit/build_angular/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ ts_json_schema(
src = "src/tslint/schema.json",
)

ts_json_schema(
name = "ng_packagr_schema",
src = "src/ng-packagr/schema.json",
)

ts_library(
name = "build_angular",
srcs = glob(
Expand All @@ -77,6 +82,7 @@ ts_library(
"//packages/angular_devkit/build_angular:src/protractor/schema.ts",
"//packages/angular_devkit/build_angular:src/server/schema.ts",
"//packages/angular_devkit/build_angular:src/tslint/schema.ts",
"//packages/angular_devkit/build_angular:src/ng-packagr/schema.ts",
],
data = glob(
include = [
Expand Down Expand Up @@ -145,6 +151,7 @@ ts_library(
"@npm//loader-utils",
"@npm//mini-css-extract-plugin",
"@npm//minimatch",
"@npm//ng-packagr",
"@npm//open",
"@npm//parse5",
"@npm//parse5-htmlparser2-tree-adapter",
Expand Down Expand Up @@ -302,6 +309,7 @@ LARGE_SPECS = {
"@npm//@angular/platform-server",
],
},
"ng-packagr": {},
"browser": {
"shards": 50,
"size": "large",
Expand Down
15 changes: 10 additions & 5 deletions packages/angular_devkit/build_angular/builders.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@
"app-shell": {
"implementation": "./src/app-shell",
"schema": "./src/app-shell/schema.json",
"description": "Build a server app and a browser app, then render the index.html and use it for the browser output."
"description": "Build a server application and a browser application, then render the index.html and use it for the browser output."
},
"browser": {
"implementation": "./src/browser",
"schema": "./src/browser/schema.json",
"description": "Build a browser app."
"description": "Build a browser application."
},
"dev-server": {
"implementation": "./src/dev-server",
"schema": "./src/dev-server/schema.json",
"description": "Serve a browser app."
"description": "Serve a browser application."
},
"extract-i18n": {
"implementation": "./src/extract-i18n",
"schema": "./src/extract-i18n/schema.json",
"description": "Extract i18n strings from a browser app."
"description": "Extract i18n strings from a browser application."
},
"karma": {
"implementation": "./src/karma",
Expand All @@ -34,12 +34,17 @@
"tslint": {
"implementation": "./src/tslint",
"schema": "./src/tslint/schema.json",
"description": "Run tslint over a TS project."
"description": "Run tslint over a TypeScript project."
},
"server": {
"implementation": "./src/server",
"schema": "./src/server/schema.json",
"description": "Build a server Angular application."
},
"ng-packagr": {
"implementation": "./src/ng-packagr",
"schema": "./src/ng-packagr/schema.json",
"description": "Build a library with ng-packagr."
}
}
}
4 changes: 4 additions & 0 deletions packages/angular_devkit/build_angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,15 @@
},
"peerDependencies": {
"@angular/compiler-cli": ">=10.1.0-next.0 < 11",
"ng-packagr": "^10.0.0",
"typescript": ">=3.9 < 3.10"
},
"peerDependenciesMeta": {
"@angular/localize": {
"optional": true
},
"ng-packagr": {
"optional": true
}
}
}
5 changes: 5 additions & 0 deletions packages/angular_devkit/build_angular/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,8 @@ export {
ServerBuilderOptions,
ServerBuilderOutput,
} from './server';

export {
execute as executeNgPackagrBuilder,
NgPackagrBuilderOptions,
} from './ng-packagr';
40 changes: 40 additions & 0 deletions packages/angular_devkit/build_angular/src/ng-packagr/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { resolve } from 'path';
import { Observable, from } from 'rxjs';
import { mapTo, switchMap } from 'rxjs/operators';
import { Schema as NgPackagrBuilderOptions } from './schema';

async function initialize(
options: NgPackagrBuilderOptions,
root: string,
): Promise<import('ng-packagr').NgPackagr> {
const packager = (await import('ng-packagr')).ngPackagr();

packager.forProject(resolve(root, options.project));

if (options.tsConfig) {
packager.withTsConfig(resolve(root, options.tsConfig));
}

return packager;
}

export function execute(
options: NgPackagrBuilderOptions,
context: BuilderContext,
): Observable<BuilderOutput> {
return from(initialize(options, context.workspaceRoot)).pipe(
switchMap(packager => options.watch ? packager.watch() : packager.build()),
mapTo({ success: true }),
);
}

export { NgPackagrBuilderOptions };
export default createBuilder<Record<string, string> & NgPackagrBuilderOptions>(execute);
25 changes: 25 additions & 0 deletions packages/angular_devkit/build_angular/src/ng-packagr/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "ng-packagr Target",
"description": "ng-packagr target options for Build Architect. Use to build library projects.",
"type": "object",
"properties": {
"project": {
"type": "string",
"description": "The file path for the ng-packagr configuration file, relative to the current workspace."
},
"tsConfig": {
"type": "string",
"description": "The full path for the TypeScript configuration file, relative to the current workspace."
},
"watch": {
"type": "boolean",
"description": "Run build when files change.",
"default": false
}
},
"additionalProperties": false,
"required": [
"project"
]
}
128 changes: 128 additions & 0 deletions packages/angular_devkit/build_angular/src/ng-packagr/works_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Architect } from '@angular-devkit/architect';
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
import { TestProjectHost, TestingArchitectHost } from '@angular-devkit/architect/testing';
import {
getSystemPath,
join,
normalize,
schema,
virtualFs,
workspaces,
} from '@angular-devkit/core';
import { map, take, tap } from 'rxjs/operators';
import { veEnabled } from '../test-utils';

// Default timeout for large specs is 2.5 minutes.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000;


describe('NgPackagr Builder', () => {
const workspaceRoot = join(normalize(__dirname), `../../test/hello-world-lib/`);
const host = new TestProjectHost(workspaceRoot);
let architect: Architect;

beforeEach(async () => {
await host.initialize().toPromise();

const registry = new schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);

const workspaceSysPath = getSystemPath(host.root());
const { workspace } = await workspaces.readWorkspace(
workspaceSysPath,
workspaces.createWorkspaceHost(host),
);
const architectHost = new TestingArchitectHost(
workspaceSysPath,
workspaceSysPath,
new WorkspaceNodeModulesArchitectHost(workspace, workspaceSysPath),
);

architect = new Architect(architectHost, registry);

// Set AOT compilation to use VE if needed.
if (veEnabled) {
host.replaceInFile('tsconfig.json', `"enableIvy": true,`, `"enableIvy": false,`);
}
});

afterEach(() => host.restore().toPromise());

it('builds and packages a library', async () => {
const run = await architect.scheduleTarget({ project: 'lib', target: 'build' });

await expectAsync(run.result).toBeResolvedTo(jasmine.objectContaining({ success: true }));

await run.stop();

expect(host.scopedSync().exists(normalize('./dist/lib/fesm2015/lib.js'))).toBe(true);
const content = virtualFs.fileBufferToString(
host.scopedSync().read(normalize('./dist/lib/fesm2015/lib.js')),
);
expect(content).toContain('lib works');

if (veEnabled) {
expect(content).not.toContain('ɵcmp');
} else {
expect(content).toContain('ɵcmp');
}
});

it('rebuilds on TS file changes', async () => {
const goldenValueFiles: { [path: string]: string } = {
'projects/lib/src/lib/lib.component.ts': `
import { Component } from '@angular/core';
@Component({
selector: 'lib',
template: 'lib update works!'
})
export class LibComponent { }
`,
};

const run = await architect.scheduleTarget(
{ project: 'lib', target: 'build' },
{ watch: true },
);

let buildNumber = 0;

await run.output.pipe(
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
map(() => {
const fileName = './dist/lib/fesm2015/lib.js';
const content = virtualFs.fileBufferToString(
host.scopedSync().read(normalize(fileName)),
);

return content;
}),
tap(content => {
buildNumber += 1;
switch (buildNumber) {
case 1:
expect(content).toMatch(/lib works/);
host.writeMultipleFiles(goldenValueFiles);
break;

case 2:
expect(content).toMatch(/lib update works/);
break;
default:
break;
}
}),
take(2),
).toPromise();

await run.stop();
});
});

0 comments on commit e5b29ac

Please sign in to comment.