refactor(ivy): ngcc - make `EntryPointJsonProperty`-related types and checks a little more strict (#32052)

PR Close #32052
This commit is contained in:
George Kalpakas 2019-08-06 00:53:38 +03:00 committed by Alex Rickabaugh
parent 9537b2ff84
commit 3077c9a1f8
5 changed files with 54 additions and 17 deletions

View File

@ -9,7 +9,7 @@
import {DepGraph} from 'dependency-graph';
import {AbsoluteFsPath, FileSystem, resolve} from '../../../src/ngtsc/file_system';
import {Logger} from '../logging/logger';
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointFormat} from '../packages/entry_point';
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from '../packages/entry_point';
import {DependencyHost, DependencyInfo} from './dependency_host';
const builtinNodeJsModules = new Set<string>(require('module').builtinModules);
@ -177,16 +177,16 @@ export class DependencyResolver {
private getEntryPointFormatInfo(entryPoint: EntryPoint):
{format: EntryPointFormat, path: AbsoluteFsPath} {
const properties = Object.keys(entryPoint.packageJson);
for (let i = 0; i < properties.length; i++) {
const property = properties[i] as EntryPointJsonProperty;
const format = getEntryPointFormat(this.fs, entryPoint, property);
for (const property of SUPPORTED_FORMAT_PROPERTIES) {
const formatPath = entryPoint.packageJson[property];
if (formatPath === undefined) continue;
if (format === 'esm2015' || format === 'esm5' || format === 'umd' || format === 'commonjs') {
const formatPath = entryPoint.packageJson[property] !;
return {format, path: resolve(entryPoint.path, formatPath)};
}
const format = getEntryPointFormat(this.fs, entryPoint, property);
if (format === undefined) continue;
return {format, path: resolve(entryPoint.path, formatPath)};
}
throw new Error(
`There is no appropriate source code format in '${entryPoint.path}' entry-point.`);
}

View File

@ -82,6 +82,8 @@ export function mainNgcc(
{basePath, targetEntryPointPath, propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES,
compileAllFormats = true, createNewEntryPointFormats = false,
logger = new ConsoleLogger(LogLevel.info), pathMappings}: NgccOptions): void {
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
const fileSystem = getFileSystem();
const transformer = new Transformer(fileSystem, logger);
const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
@ -99,7 +101,7 @@ export function mainNgcc(
const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats);
const entryPoints = getEntryPoints(
fileSystem, config, logger, resolver, absBasePath, targetEntryPointPath, pathMappings,
propertiesToConsider, compileAllFormats);
supportedPropertiesToConsider, compileAllFormats);
for (const entryPoint of entryPoints) {
// Are we compiling the Angular core?
const isCore = entryPoint.name === '@angular/core';
@ -111,7 +113,7 @@ export function mainNgcc(
let processDts = !hasBeenProcessed(entryPointPackageJson, 'typings');
for (const property of propertiesToConsider as EntryPointJsonProperty[]) {
for (const property of supportedPropertiesToConsider) {
// If we only need one format processed and we already have one, exit the loop.
if (!compileAllFormats && (compiledFormats.size > 0)) break;
@ -139,7 +141,8 @@ export function mainNgcc(
fileWriter.writeBundle(entryPoint, bundle, transformedFiles);
compiledFormats.add(formatPath);
const propsToMarkAsProcessed = pathToPropsMap.get(formatPath) !;
const propsToMarkAsProcessed: (EntryPointJsonProperty | 'typings')[] =
pathToPropsMap.get(formatPath) !;
if (processDts) {
propsToMarkAsProcessed.push('typings');
processDts = false;
@ -152,11 +155,33 @@ export function mainNgcc(
if (compiledFormats.size === 0) {
throw new Error(
`Failed to compile any formats for entry-point at (${entryPoint.path}). Tried ${propertiesToConsider}.`);
`Failed to compile any formats for entry-point at (${entryPoint.path}). Tried ${supportedPropertiesToConsider}.`);
}
}
}
function ensureSupportedProperties(properties: string[]): EntryPointJsonProperty[] {
// Short-circuit the case where `properties` has fallen back to the default value:
// `SUPPORTED_FORMAT_PROPERTIES`
if (properties === SUPPORTED_FORMAT_PROPERTIES) return SUPPORTED_FORMAT_PROPERTIES;
const supportedProperties: EntryPointJsonProperty[] = [];
for (const prop of properties as EntryPointJsonProperty[]) {
if (SUPPORTED_FORMAT_PROPERTIES.indexOf(prop) !== -1) {
supportedProperties.push(prop);
}
}
if (supportedProperties.length === 0) {
throw new Error(
`No supported format property to consider among [${properties.join(', ')}]. ` +
`Supported properties: ${SUPPORTED_FORMAT_PROPERTIES.join(', ')}`);
}
return supportedProperties;
}
function getFileWriter(fs: FileSystem, createNewEntryPointFormats: boolean): FileWriter {
return createNewEntryPointFormats ? new NewEntryPointFileWriter(fs) : new InPlaceFileWriter(fs);
}

View File

@ -23,7 +23,7 @@ export const NGCC_VERSION = '0.0.0-PLACEHOLDER';
* @throws Error if the entry-point has already been processed with a different ngcc version.
*/
export function hasBeenProcessed(
packageJson: EntryPointPackageJson, format: EntryPointJsonProperty): boolean {
packageJson: EntryPointPackageJson, format: EntryPointJsonProperty | 'typings'): boolean {
if (!packageJson.__processed_by_ivy_ngcc__) {
return false;
}
@ -49,7 +49,7 @@ export function hasBeenProcessed(
*/
export function markAsProcessed(
fs: FileSystem, packageJson: EntryPointPackageJson, packageJsonPath: AbsoluteFsPath,
properties: EntryPointJsonProperty[]) {
properties: (EntryPointJsonProperty | 'typings')[]) {
const processed =
packageJson.__processed_by_ivy_ngcc__ || (packageJson.__processed_by_ivy_ngcc__ = {});

View File

@ -58,7 +58,7 @@ export interface EntryPointPackageJson extends PackageJsonFormatProperties {
__processed_by_ivy_ngcc__?: {[key: string]: string};
}
export type EntryPointJsonProperty = keyof(PackageJsonFormatProperties);
export type EntryPointJsonProperty = Exclude<keyof PackageJsonFormatProperties, 'types'|'typings'>;
// We need to keep the elements of this const and the `EntryPointJsonProperty` type in sync.
export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
['fesm2015', 'fesm5', 'es2015', 'esm2015', 'esm5', 'main', 'module'];
@ -122,7 +122,8 @@ export function getEntryPointInfo(
* @returns An entry-point format or `undefined` if none match the given property.
*/
export function getEntryPointFormat(
fs: FileSystem, entryPoint: EntryPoint, property: string): EntryPointFormat|undefined {
fs: FileSystem, entryPoint: EntryPoint, property: EntryPointJsonProperty): EntryPointFormat|
undefined {
switch (property) {
case 'fesm2015':
return 'esm2015';

View File

@ -200,6 +200,17 @@ runInEachFileSystem(() => {
describe('with propertiesToConsider', () => {
it('should complain if none of the properties in the `propertiesToConsider` list is supported',
() => {
const propertiesToConsider = ['es1337', 'fesm42'];
const errorMessage =
'No supported format property to consider among [es1337, fesm42]. Supported ' +
'properties: fesm2015, fesm5, es2015, esm2015, esm5, main, module';
expect(() => mainNgcc({basePath: '/node_modules', propertiesToConsider}))
.toThrowError(errorMessage);
});
it('should only compile the entry-point formats given in the `propertiesToConsider` list',
() => {
mainNgcc({