feat(ivy): ngcc - compile only specified package.json format properties (#29092)

You can now specify a list of properties in the package.json that
should be considered (in order) to find the path to the format to compile.

The build marker system has been updated to store the markers in
the package.json rather than an additional external file.
Also instead of tracking the underlying bundle format that was compiled,
it now tracks the package.json property.

BREAKING CHANGE:

The `proertiesToConsider` option replaces the previous `formats` option,
which specified the final bundle format, rather than the property in the
package.json.
If you were using this option to compile only specific bundle formats,
you must now modify your usage to pass in the properties in the package.json
that map to the format that you wish to compile.

In the CLI, the `--formats` is no longer available. Instead use the
`--properties` option.

FW-1120

PR Close #29092
This commit is contained in:
Pete Bacon Darwin
2019-03-20 13:47:58 +00:00
committed by Matias Niemelä
parent 4bb0259bc0
commit cd449021c1
11 changed files with 355 additions and 270 deletions

View File

@ -19,38 +19,74 @@ describe('ngcc main()', () => {
afterEach(restoreRealFileSystem);
it('should run ngcc without errors for fesm2015', () => {
expect(() => mainNgcc({baseSourcePath: '/node_modules', formats: ['fesm2015']})).not.toThrow();
expect(() => mainNgcc({baseSourcePath: '/node_modules', propertiesToConsider: ['fesm2015']}))
.not.toThrow();
});
it('should run ngcc without errors for fesm5', () => {
expect(() => mainNgcc({baseSourcePath: '/node_modules', formats: ['fesm5']})).not.toThrow();
expect(() => mainNgcc({baseSourcePath: '/node_modules', propertiesToConsider: ['fesm5']}))
.not.toThrow();
});
it('should run ngcc without errors for esm2015', () => {
expect(() => mainNgcc({baseSourcePath: '/node_modules', formats: ['esm2015']})).not.toThrow();
expect(() => mainNgcc({baseSourcePath: '/node_modules', propertiesToConsider: ['esm2015']}))
.not.toThrow();
});
it('should run ngcc without errors for esm5', () => {
expect(() => mainNgcc({baseSourcePath: '/node_modules', formats: ['esm5']})).not.toThrow();
expect(() => mainNgcc({baseSourcePath: '/node_modules', propertiesToConsider: ['esm5']}))
.not.toThrow();
});
it('should only compile the given package entry-point (and its dependencies)', () => {
mainNgcc({
baseSourcePath: '/node_modules',
formats: ['esm2015'],
targetEntryPointPath: '@angular/common'
});
mainNgcc({baseSourcePath: '/node_modules', targetEntryPointPath: '@angular/common/http'});
expect(loadPackage('@angular/common').__modified_by_ngcc__).toEqual({
esm2015: '0.0.0-PLACEHOLDER',
expect(loadPackage('@angular/common/http').__modified_by_ngcc__).toEqual({
module: '0.0.0-PLACEHOLDER',
es2015: '0.0.0-PLACEHOLDER',
esm5: '0.0.0-PLACEHOLDER',
esm2015: '0.0.0-PLACEHOLDER',
fesm5: '0.0.0-PLACEHOLDER',
fesm2015: '0.0.0-PLACEHOLDER'
});
expect(loadPackage('@angular/common').__modified_by_ngcc__).toEqual({
module: '0.0.0-PLACEHOLDER',
es2015: '0.0.0-PLACEHOLDER',
esm5: '0.0.0-PLACEHOLDER',
esm2015: '0.0.0-PLACEHOLDER',
fesm5: '0.0.0-PLACEHOLDER',
fesm2015: '0.0.0-PLACEHOLDER'
});
expect(loadPackage('@angular/core').__modified_by_ngcc__).toEqual({
esm2015: '0.0.0-PLACEHOLDER',
module: '0.0.0-PLACEHOLDER',
es2015: '0.0.0-PLACEHOLDER',
esm5: '0.0.0-PLACEHOLDER',
esm2015: '0.0.0-PLACEHOLDER',
fesm5: '0.0.0-PLACEHOLDER',
fesm2015: '0.0.0-PLACEHOLDER'
});
expect(loadPackage('@angular/common/testing').__modified_by_ngcc__).toBeUndefined();
expect(loadPackage('@angular/common/http').__modified_by_ngcc__).toBeUndefined();
});
it('should only build the format properties specified for each entry-point', () => {
mainNgcc({baseSourcePath: '/node_modules', propertiesToConsider: ['main', 'esm5', 'module']});
expect(loadPackage('@angular/core').__modified_by_ngcc__).toEqual({
esm5: '0.0.0-PLACEHOLDER',
module: '0.0.0-PLACEHOLDER',
});
expect(loadPackage('@angular/common').__modified_by_ngcc__).toEqual({
esm5: '0.0.0-PLACEHOLDER',
module: '0.0.0-PLACEHOLDER',
});
expect(loadPackage('@angular/common/testing').__modified_by_ngcc__).toEqual({
esm5: '0.0.0-PLACEHOLDER',
module: '0.0.0-PLACEHOLDER',
});
expect(loadPackage('@angular/common/http').__modified_by_ngcc__).toEqual({
esm5: '0.0.0-PLACEHOLDER',
module: '0.0.0-PLACEHOLDER',
});
});
});

View File

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {existsSync, readFileSync, writeFileSync} from 'fs';
import {readFileSync, writeFileSync} from 'fs';
import * as mockFs from 'mock-fs';
import {checkMarkerFile, writeMarkerFile} from '../../src/packages/build_marker';
import {checkMarker, writeMarker} from '../../src/packages/build_marker';
import {EntryPoint} from '../../src/packages/entry_point';
function createMockFileSystem() {
@ -94,58 +94,55 @@ function restoreRealFileSystem() {
}
function createEntryPoint(path: string): EntryPoint {
return {name: 'some-package', path, package: '', typings: ''};
return {
name: 'some-package',
path,
package: path,
typings: '',
packageJson: JSON.parse(readFileSync(path + '/package.json', 'utf8'))
};
}
describe('Marker files', () => {
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
describe('writeMarkerFile', () => {
it('should write a file containing the version placeholder', () => {
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__'))
.toBe(false);
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_esm5__')).toBe(false);
describe('writeMarker', () => {
it('should write a property in the package.json containing the version placeholder', () => {
let pkg = JSON.parse(readFileSync('/node_modules/@angular/common/package.json', 'utf8'));
expect(pkg.__modified_by_ngcc__).toBeUndefined();
expect(pkg.__modified_by_ngcc__).toBeUndefined();
writeMarkerFile(createEntryPoint('/node_modules/@angular/common'), 'fesm2015');
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__'))
.toBe(true);
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_esm5__')).toBe(false);
expect(
readFileSync('/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__', 'utf8'))
.toEqual('0.0.0-PLACEHOLDER');
writeMarker(createEntryPoint('/node_modules/@angular/common'), 'fesm2015');
pkg = JSON.parse(readFileSync('/node_modules/@angular/common/package.json', 'utf8'));
expect(pkg.__modified_by_ngcc__.fesm2015).toEqual('0.0.0-PLACEHOLDER');
expect(pkg.__modified_by_ngcc__.esm5).toBeUndefined();
writeMarkerFile(createEntryPoint('/node_modules/@angular/common'), 'esm5');
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__'))
.toBe(true);
expect(existsSync('/node_modules/@angular/common/__modified_by_ngcc_for_esm5__')).toBe(true);
expect(
readFileSync('/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__', 'utf8'))
.toEqual('0.0.0-PLACEHOLDER');
expect(readFileSync('/node_modules/@angular/common/__modified_by_ngcc_for_esm5__', 'utf8'))
.toEqual('0.0.0-PLACEHOLDER');
writeMarker(createEntryPoint('/node_modules/@angular/common'), 'esm5');
pkg = JSON.parse(readFileSync('/node_modules/@angular/common/package.json', 'utf8'));
expect(pkg.__modified_by_ngcc__.fesm2015).toEqual('0.0.0-PLACEHOLDER');
expect(pkg.__modified_by_ngcc__.esm5).toEqual('0.0.0-PLACEHOLDER');
});
});
describe('checkMarkerFile', () => {
it('should return false if the marker file does not exist', () => {
expect(checkMarkerFile(createEntryPoint('/node_modules/@angular/common'), 'fesm2015'))
describe('checkMarker', () => {
it('should return false if the marker property does not exist', () => {
expect(checkMarker(createEntryPoint('/node_modules/@angular/common'), 'fesm2015'))
.toBe(false);
});
it('should return true if the marker file exists and contains the correct version', () => {
writeFileSync(
'/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__', '0.0.0-PLACEHOLDER',
'utf8');
expect(checkMarkerFile(createEntryPoint('/node_modules/@angular/common'), 'fesm2015'))
.toBe(true);
it('should return true if the marker property exists and contains the correct version', () => {
const pkg = JSON.parse(readFileSync('/node_modules/@angular/common/package.json', 'utf8'));
pkg.__modified_by_ngcc__ = {fesm2015: '0.0.0-PLACEHOLDER'};
writeFileSync('/node_modules/@angular/common/package.json', JSON.stringify(pkg), 'utf8');
expect(checkMarker(createEntryPoint('/node_modules/@angular/common'), 'fesm2015')).toBe(true);
});
it('should throw if the marker file exists but contains the wrong version', () => {
writeFileSync(
'/node_modules/@angular/common/__modified_by_ngcc_for_fesm2015__', 'WRONG_VERSION',
'utf8');
expect(() => checkMarkerFile(createEntryPoint('/node_modules/@angular/common'), 'fesm2015'))
it('should throw if the marker property exists but contains the wrong version', () => {
const pkg = JSON.parse(readFileSync('/node_modules/@angular/common/package.json', 'utf8'));
pkg.__modified_by_ngcc__ = {fesm2015: 'WRONG_VERSION'};
writeFileSync('/node_modules/@angular/common/package.json', JSON.stringify(pkg), 'utf8');
expect(() => checkMarker(createEntryPoint('/node_modules/@angular/common'), 'fesm2015'))
.toThrowError(
'The ngcc compiler has changed since the last ngcc build.\n' +
'Please completely remove `node_modules` and try again.');

View File

@ -25,7 +25,7 @@ describe('findEntryPoints()', () => {
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
it('should find sub-entry-points within a package', () => {
it('should find sub-entry-points within a package', () => {
const {entryPoints} = finder.findEntryPoints('/sub_entry_points');
const entryPointPaths = entryPoints.map(x => [x.package, x.path]);
expect(entryPointPaths).toEqual([

View File

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {readFileSync} from 'fs';
import * as mockFs from 'mock-fs';
import {getEntryPointInfo} from '../../src/packages/entry_point';
describe('getEntryPointInfo()', () => {
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
@ -27,6 +27,7 @@ describe('getEntryPointInfo()', () => {
fesm5: `/some_package/valid_entry_point/fesm2015/valid_entry_point.js`,
esm5: `/some_package/valid_entry_point/esm2015/valid_entry_point.js`,
umd: `/some_package/valid_entry_point/bundles/valid_entry_point.umd.js`,
packageJson: loadPackageJson('/some_package/valid_entry_point'),
});
});
@ -63,6 +64,7 @@ describe('getEntryPointInfo()', () => {
fesm5: `/some_package/types_rather_than_typings/fesm2015/types_rather_than_typings.js`,
esm5: `/some_package/types_rather_than_typings/esm2015/types_rather_than_typings.js`,
umd: `/some_package/types_rather_than_typings/bundles/types_rather_than_typings.umd.js`,
packageJson: loadPackageJson('/some_package/types_rather_than_typings'),
});
});
@ -76,6 +78,7 @@ describe('getEntryPointInfo()', () => {
fesm2015: `/some_package/material_style/esm2015/material_style.js`,
fesm5: `/some_package/material_style/esm5/material_style.es5.js`,
umd: `/some_package/material_style/bundles/material_style.umd.js`,
packageJson: loadPackageJson('/some_package/material_style'),
});
});
@ -154,3 +157,7 @@ function createPackageJson(
}
return JSON.stringify(packageJson);
}
export function loadPackageJson(packagePath: string) {
return JSON.parse(readFileSync(packagePath + '/package.json', 'utf8'));
}