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 {DepGraph} from 'dependency-graph';
import {AbsoluteFsPath, FileSystem, resolve} from '../../../src/ngtsc/file_system'; import {AbsoluteFsPath, FileSystem, resolve} from '../../../src/ngtsc/file_system';
import {Logger} from '../logging/logger'; 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'; import {DependencyHost, DependencyInfo} from './dependency_host';
const builtinNodeJsModules = new Set<string>(require('module').builtinModules); const builtinNodeJsModules = new Set<string>(require('module').builtinModules);
@ -177,16 +177,16 @@ export class DependencyResolver {
private getEntryPointFormatInfo(entryPoint: EntryPoint): private getEntryPointFormatInfo(entryPoint: EntryPoint):
{format: EntryPointFormat, path: AbsoluteFsPath} { {format: EntryPointFormat, path: AbsoluteFsPath} {
const properties = Object.keys(entryPoint.packageJson); for (const property of SUPPORTED_FORMAT_PROPERTIES) {
for (let i = 0; i < properties.length; i++) { const formatPath = entryPoint.packageJson[property];
const property = properties[i] as EntryPointJsonProperty; if (formatPath === undefined) continue;
const format = getEntryPointFormat(this.fs, entryPoint, property);
if (format === 'esm2015' || format === 'esm5' || format === 'umd' || format === 'commonjs') { const format = getEntryPointFormat(this.fs, entryPoint, property);
const formatPath = entryPoint.packageJson[property] !; if (format === undefined) continue;
return {format, path: resolve(entryPoint.path, formatPath)};
} return {format, path: resolve(entryPoint.path, formatPath)};
} }
throw new Error( throw new Error(
`There is no appropriate source code format in '${entryPoint.path}' entry-point.`); `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, {basePath, targetEntryPointPath, propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES,
compileAllFormats = true, createNewEntryPointFormats = false, compileAllFormats = true, createNewEntryPointFormats = false,
logger = new ConsoleLogger(LogLevel.info), pathMappings}: NgccOptions): void { logger = new ConsoleLogger(LogLevel.info), pathMappings}: NgccOptions): void {
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
const fileSystem = getFileSystem(); const fileSystem = getFileSystem();
const transformer = new Transformer(fileSystem, logger); const transformer = new Transformer(fileSystem, logger);
const moduleResolver = new ModuleResolver(fileSystem, pathMappings); const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
@ -99,7 +101,7 @@ export function mainNgcc(
const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats); const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats);
const entryPoints = getEntryPoints( const entryPoints = getEntryPoints(
fileSystem, config, logger, resolver, absBasePath, targetEntryPointPath, pathMappings, fileSystem, config, logger, resolver, absBasePath, targetEntryPointPath, pathMappings,
propertiesToConsider, compileAllFormats); supportedPropertiesToConsider, compileAllFormats);
for (const entryPoint of entryPoints) { for (const entryPoint of entryPoints) {
// Are we compiling the Angular core? // Are we compiling the Angular core?
const isCore = entryPoint.name === '@angular/core'; const isCore = entryPoint.name === '@angular/core';
@ -111,7 +113,7 @@ export function mainNgcc(
let processDts = !hasBeenProcessed(entryPointPackageJson, 'typings'); 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 we only need one format processed and we already have one, exit the loop.
if (!compileAllFormats && (compiledFormats.size > 0)) break; if (!compileAllFormats && (compiledFormats.size > 0)) break;
@ -139,7 +141,8 @@ export function mainNgcc(
fileWriter.writeBundle(entryPoint, bundle, transformedFiles); fileWriter.writeBundle(entryPoint, bundle, transformedFiles);
compiledFormats.add(formatPath); compiledFormats.add(formatPath);
const propsToMarkAsProcessed = pathToPropsMap.get(formatPath) !; const propsToMarkAsProcessed: (EntryPointJsonProperty | 'typings')[] =
pathToPropsMap.get(formatPath) !;
if (processDts) { if (processDts) {
propsToMarkAsProcessed.push('typings'); propsToMarkAsProcessed.push('typings');
processDts = false; processDts = false;
@ -152,11 +155,33 @@ export function mainNgcc(
if (compiledFormats.size === 0) { if (compiledFormats.size === 0) {
throw new Error( 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 { function getFileWriter(fs: FileSystem, createNewEntryPointFormats: boolean): FileWriter {
return createNewEntryPointFormats ? new NewEntryPointFileWriter(fs) : new InPlaceFileWriter(fs); 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. * @throws Error if the entry-point has already been processed with a different ngcc version.
*/ */
export function hasBeenProcessed( export function hasBeenProcessed(
packageJson: EntryPointPackageJson, format: EntryPointJsonProperty): boolean { packageJson: EntryPointPackageJson, format: EntryPointJsonProperty | 'typings'): boolean {
if (!packageJson.__processed_by_ivy_ngcc__) { if (!packageJson.__processed_by_ivy_ngcc__) {
return false; return false;
} }
@ -49,7 +49,7 @@ export function hasBeenProcessed(
*/ */
export function markAsProcessed( export function markAsProcessed(
fs: FileSystem, packageJson: EntryPointPackageJson, packageJsonPath: AbsoluteFsPath, fs: FileSystem, packageJson: EntryPointPackageJson, packageJsonPath: AbsoluteFsPath,
properties: EntryPointJsonProperty[]) { properties: (EntryPointJsonProperty | 'typings')[]) {
const processed = const processed =
packageJson.__processed_by_ivy_ngcc__ || (packageJson.__processed_by_ivy_ngcc__ = {}); 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}; __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. // We need to keep the elements of this const and the `EntryPointJsonProperty` type in sync.
export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] = export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
['fesm2015', 'fesm5', 'es2015', 'esm2015', 'esm5', 'main', 'module']; ['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. * @returns An entry-point format or `undefined` if none match the given property.
*/ */
export function getEntryPointFormat( export function getEntryPointFormat(
fs: FileSystem, entryPoint: EntryPoint, property: string): EntryPointFormat|undefined { fs: FileSystem, entryPoint: EntryPoint, property: EntryPointJsonProperty): EntryPointFormat|
undefined {
switch (property) { switch (property) {
case 'fesm2015': case 'fesm2015':
return 'esm2015'; return 'esm2015';

View File

@ -200,6 +200,17 @@ runInEachFileSystem(() => {
describe('with propertiesToConsider', () => { 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', it('should only compile the entry-point formats given in the `propertiesToConsider` list',
() => { () => {
mainNgcc({ mainNgcc({