Skip to content

Commit 1f79aa2

Browse files
alan-agius4dherges
authored andcommitted
feat: build only entrypoints that are effected by the change (#991)
When the public API that is consumed from another entrypoint changes, the updated API changes are now reflected in the secondary entrypoint. Also, now only entrypoints that are effected by this file change will be marked as `dirty` and therefore scheduled to be build. Relates: #974
1 parent 6629963 commit 1f79aa2

24 files changed

+311
-45
lines changed

integration/watch/basic.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ describe('basic', () => {
1919
describe('primary entrypoint', () => {
2020
it("should perform initial compilation when 'watch' is started", () => {
2121
harness.expectDtsToMatch('public_api', /title = "hello world"/);
22-
harness.expectFesm5ToContain('basic', 'title', 'hello world');
23-
harness.expectFesm2015ToContain('basic', 'title', 'hello world');
22+
harness.expectFesm5ToMatch('basic', /hello world/);
23+
harness.expectFesm2015ToMatch('basic', /hello world/);
2424
harness.expectMetadataToContain('basic', 'metadata.title', 'hello world');
2525
});
2626

@@ -30,8 +30,8 @@ describe('basic', () => {
3030

3131
harness.onComplete(() => {
3232
harness.expectDtsToMatch('public_api', /title = "foo bar"/);
33-
harness.expectFesm5ToContain('basic', 'title', 'foo bar');
34-
harness.expectFesm2015ToContain('basic', 'title', 'foo bar');
33+
harness.expectFesm5ToMatch('basic', /foo bar/);
34+
harness.expectFesm2015ToMatch('basic', /foo bar/);
3535
harness.expectMetadataToContain('basic', 'metadata.title', 'foo bar');
3636
done();
3737
});
@@ -42,8 +42,8 @@ describe('basic', () => {
4242

4343
harness.onComplete(() => {
4444
harness.expectDtsToMatch('public_api', /title = "foo bar"/);
45-
harness.expectFesm5ToContain('basic', 'title', 'foo bar');
46-
harness.expectFesm2015ToContain('basic', 'title', 'foo bar');
45+
harness.expectFesm5ToMatch('basic', /foo bar/);
46+
harness.expectFesm2015ToMatch('basic', /foo bar/);
4747
harness.expectMetadataToContain('basic', 'metadata.title', 'foo bar');
4848
done();
4949
});
@@ -62,8 +62,8 @@ describe('basic', () => {
6262
harness.copyTestCase('secondary-valid');
6363

6464
harness.onComplete(() => {
65-
harness.expectFesm5ToContain('basic-secondary', 'ɵa.decorators[0].args[0].template', 'Hello Angular');
66-
harness.expectFesm2015ToContain('basic-secondary', 'ɵa.decorators[0].args[0].template', 'Hello Angular');
65+
harness.expectFesm5ToMatch('basic-secondary', /Hello Angular/);
66+
harness.expectFesm2015ToMatch('basic-secondary', /Hello Angular/);
6767
harness.expectMetadataToContain(
6868
'secondary/basic-secondary',
6969
'metadata.ɵa.decorators[0].arguments[0].template',
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { expect } from 'chai';
2+
import * as fs from 'fs';
3+
import { TestHarness } from './test-harness';
4+
5+
describe('intra-dependent', () => {
6+
const harness = new TestHarness('intra-dependent');
7+
8+
before(async () => {
9+
await harness.initialize();
10+
});
11+
12+
afterEach(() => {
13+
harness.reset();
14+
});
15+
16+
after(() => {
17+
harness.dispose();
18+
});
19+
20+
it("should perform initial compilation when 'watch' is started", () => {
21+
harness.expectDtsToMatch('src/primary.component', /count: number/);
22+
harness.expectFesm5ToMatch('intra-dependent-secondary', /count = 100/);
23+
harness.expectFesm2015ToMatch('intra-dependent-secondary', /count = 100/);
24+
});
25+
26+
it('should throw error component inputs is changed without updating usages', done => {
27+
harness.copyTestCase('invalid-component-property');
28+
29+
harness.onFailure(error => {
30+
expect(error.message).to.match(/Can\'t bind to \'count\' since it isn\'t a known property/);
31+
harness.copyTestCase('valid');
32+
done();
33+
});
34+
});
35+
36+
it('should throw error service method is changed without updating usages', done => {
37+
harness.copyTestCase('invalid-service-method');
38+
39+
harness.onFailure(error => {
40+
expect(error.message).to.match(/Property \'initialize\' does not exist on type \'PrimaryAngularService\'/);
41+
harness.copyTestCase('valid');
42+
done();
43+
});
44+
});
45+
46+
it('should only build entrypoints that are dependent on the file changed.', done => {
47+
const primaryFesmPath = harness.getFilePath('fesm5/intra-dependent.js');
48+
const secondaryFesmPath = harness.getFilePath('fesm5/intra-dependent-secondary.js');
49+
const thirdFesmPath = harness.getFilePath('fesm5/intra-dependent-third.js');
50+
51+
const primaryModifiedTime = fs.statSync(primaryFesmPath).mtimeMs;
52+
const secondaryModifiedTime = fs.statSync(secondaryFesmPath).mtimeMs;
53+
const thirdModifiedTime = fs.statSync(thirdFesmPath).mtimeMs;
54+
harness.copyTestCase('valid');
55+
56+
harness.onComplete(() => {
57+
expect(fs.statSync(primaryFesmPath).mtimeMs).to.greaterThan(primaryModifiedTime);
58+
expect(fs.statSync(secondaryFesmPath).mtimeMs).to.greaterThan(secondaryModifiedTime);
59+
expect(fs.statSync(thirdFesmPath).mtimeMs).to.equals(thirdModifiedTime);
60+
done();
61+
});
62+
});
63+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$schema": "../../../src/package.schema.json",
3+
"name": "intra-dependent",
4+
"description": "A sample library testing Angular Package Format",
5+
"version": "1.0.0-pre.0",
6+
"private": true,
7+
"repository": "https://github.com/dherges/ng-packagr.git",
8+
"main": "dist/bundles/intra-dependent.umd.js",
9+
"peerDependencies": {
10+
"@angular/core": "^4.1.2",
11+
"@angular/common": "^4.1.2"
12+
},
13+
"ngPackage": {
14+
"lib": {
15+
"entryFile": "public_api.ts"
16+
}
17+
}
18+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { PrimaryAngularModule } from './src/primary.module';
2+
export { PrimaryAngularComponent } from './src/primary.component';
3+
export { PrimaryAngularService } from './src/primary.service';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "../../../../src/package.schema.json",
3+
"description": "A secondary entry point",
4+
"private": true,
5+
"repository": "https://github.com/dherges/ng-packagr.git",
6+
"ngPackage": {
7+
"lib": {
8+
"entryFile": "public_api.ts"
9+
}
10+
}
11+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { SecondaryAngularModule } from './src/secondary.module';
2+
export { SecondaryAngularComponent } from './src/secondary.component';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Component } from '@angular/core';
2+
import { PrimaryAngularService } from 'intra-dependent';
3+
4+
@Component({
5+
selector: 'ng-component-secondary',
6+
template: '<ng-component [count]="count"></ng-component>'
7+
})
8+
export class SecondaryAngularComponent {
9+
count = 100;
10+
11+
constructor(service: PrimaryAngularService) {
12+
service.initialize();
13+
}
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { SecondaryAngularComponent } from './secondary.component';
4+
import { PrimaryAngularModule } from 'intra-dependent';
5+
6+
@NgModule({
7+
imports: [CommonModule, PrimaryAngularModule],
8+
declarations: [SecondaryAngularComponent],
9+
exports: [SecondaryAngularComponent]
10+
})
11+
export class SecondaryAngularModule {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Component, Input } from '@angular/core';
2+
3+
@Component({
4+
selector: 'ng-component',
5+
template: '{{ count }}'
6+
})
7+
export class PrimaryAngularComponent {
8+
@Input() count: number;
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { PrimaryAngularComponent } from './primary.component';
4+
import { PrimaryAngularService } from './primary.service';
5+
6+
@NgModule({
7+
imports: [CommonModule],
8+
declarations: [PrimaryAngularComponent],
9+
providers: [PrimaryAngularService],
10+
exports: [PrimaryAngularComponent]
11+
})
12+
export class PrimaryAngularModule {}

0 commit comments

Comments
 (0)