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

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {checkMarkerFile, writeMarkerFile} from './packages/build_marker';
import {checkMarker, writeMarker} from './packages/build_marker';
import {DependencyHost} from './packages/dependency_host';
import {DependencyResolver} from './packages/dependency_resolver';
import {EntryPointFormat} from './packages/entry_point';
import {EntryPointFormat, EntryPointJsonProperty, getEntryPointFormat} from './packages/entry_point';
import {makeEntryPointBundle} from './packages/entry_point_bundle';
import {EntryPointFinder} from './packages/entry_point_finder';
import {Transformer} from './packages/transformer';
@ -20,8 +20,6 @@ import {Transformer} from './packages/transformer';
export interface NgccOptions {
/** The path to the node_modules folder that contains the packages to compile. */
baseSourcePath: string;
/** A list of JavaScript bundle formats that should be compiled. */
formats: EntryPointFormat[];
/** The path to the node_modules folder where modified files should be written. */
baseTargetPath?: string;
/**
@ -29,8 +27,15 @@ export interface NgccOptions {
* All its dependencies will need to be compiled too.
*/
targetEntryPointPath?: string;
/**
* Which entry-point properties in the package.json to consider when compiling.
* Each of properties contain a path to particular bundle format for a given entry-point.
*/
propertiesToConsider?: EntryPointJsonProperty[];
}
const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015', 'fesm5', 'fesm2015'];
/**
* This is the main entry-point into ngcc (aNGular Compatibility Compiler).
*
@ -39,8 +44,8 @@ export interface NgccOptions {
*
* @param options The options telling ngcc what to compile and how.
*/
export function mainNgcc({baseSourcePath, formats, baseTargetPath = baseSourcePath,
targetEntryPointPath}: NgccOptions): void {
export function mainNgcc({baseSourcePath, baseTargetPath = baseSourcePath, targetEntryPointPath,
propertiesToConsider}: NgccOptions): void {
const transformer = new Transformer(baseSourcePath, baseTargetPath);
const host = new DependencyHost();
const resolver = new DependencyResolver(host);
@ -52,28 +57,51 @@ export function mainNgcc({baseSourcePath, formats, baseTargetPath = baseSourcePa
// Are we compiling the Angular core?
const isCore = entryPoint.name === '@angular/core';
// We transform the d.ts typings files while transforming one of the formats.
// This variable decides with which of the available formats to do this transform.
// It is marginally faster to process via the flat file if available.
const dtsTransformFormat: EntryPointFormat = entryPoint.fesm2015 ? 'fesm2015' : 'esm2015';
let dtsTransformFormat: EntryPointFormat|undefined;
formats.forEach(format => {
if (checkMarkerFile(entryPoint, format)) {
console.warn(`Skipping ${entryPoint.name} : ${format} (already built).`);
return;
const propertiesToCompile =
propertiesToConsider || Object.keys(entryPoint.packageJson) as EntryPointJsonProperty[];
const compiledFormats = new Set<EntryPointFormat>();
for (let i = 0; i < propertiesToCompile.length; i++) {
const property = propertiesToCompile[i];
const format = getEntryPointFormat(entryPoint.packageJson, property);
// No format then this property is not supposed to be compiled.
if (!format || SUPPORTED_FORMATS.indexOf(format) === -1) continue;
// We don't want to compile a format more than once.
// This could happen if there are multiple properties that map to the same format...
// E.g. `fesm5` and `module` both can point to the flat ESM5 format.
if (!compiledFormats.has(format)) {
compiledFormats.add(format);
// Use the first format found for typings transformation.
dtsTransformFormat = dtsTransformFormat || format;
if (checkMarker(entryPoint, property)) {
const bundle =
makeEntryPointBundle(entryPoint, isCore, format, format === dtsTransformFormat);
if (bundle) {
transformer.transform(entryPoint, isCore, bundle);
} else {
console.warn(
`Skipping ${entryPoint.name} : ${format} (no entry point file for this format).`);
}
} else {
console.warn(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
}
}
// Write the built-with-ngcc marker.
writeMarker(entryPoint, property);
}
const bundle =
makeEntryPointBundle(entryPoint, isCore, format, format === dtsTransformFormat);
if (bundle === null) {
console.warn(
`Skipping ${entryPoint.name} : ${format} (no entry point file for this format).`);
} else {
transformer.transform(entryPoint, isCore, bundle);
}
// Write the built-with-ngcc marker
writeMarkerFile(entryPoint, format);
});
if (!dtsTransformFormat) {
throw new Error(
`Failed to compile any formats for entry-point at (${entryPoint.path}). Tried ${propertiesToCompile}.`);
}
});
}
export {NGCC_VERSION} from './packages/build_marker';