-
Notifications
You must be signed in to change notification settings - Fork 12k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(@angular-devkit/build-angular): add
ng-packagr
builder in `@an…
…gular-devkit/build-angular` With this change we add the `ng-packagr` builder in `@angular-devkit/build-angular`
- Loading branch information
1 parent
ba7f6e8
commit e5b29ac
Showing
7 changed files
with
220 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
packages/angular_devkit/build_angular/src/ng-packagr/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
25
packages/angular_devkit/build_angular/src/ng-packagr/schema.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
128
packages/angular_devkit/build_angular/src/ng-packagr/works_spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); | ||
}); |