Skip to content

Commit

Permalink
fix(ivy): ngcc - correctly update package.json when `createNewEntry…
Browse files Browse the repository at this point in the history
…PointFormats` is true

Previously, when run with `createNewEntryPointFormats: true`, `ngcc`
would only update `package.json` with the new entry-point for the first
format property that mapped to a format-path. Subsequent properties
mapping to the same format-path would be detected as processed and not
have their new entry-point format recorded in `package.json`.

This commit fixes this by ensuring `package.json` is updated for all
matching format properties, when writing an `EntryPointBundle`.
  • Loading branch information
gkalpak committed Aug 8, 2019
1 parent fcd5af0 commit 366c3ea
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 44 deletions.
14 changes: 7 additions & 7 deletions packages/compiler-cli/ngcc/src/execution/api.ts
Expand Up @@ -29,13 +29,6 @@ export type ExecuteFn = (analyzeFn: AnalyzeFn, createCompileFn: CreateCompileFn)

/** Represents metadata related to the processing of an entry-point. */
export interface EntryPointProcessingMetadata {
/**
* A mapping from a format property (i.e. an `EntryPointJsonProperty`) to the list of format
* properties that point to the same format-path and as a result need to be marked as processed,
* once the former is processed.
*/
propertyToPropertiesToMarkAsProcessed: Map<EntryPointJsonProperty, EntryPointJsonProperty[]>;

/**
* Whether the typings for the entry-point have been successfully processed (or were already
* processed).
Expand All @@ -60,6 +53,13 @@ export interface Task {
*/
formatProperty: EntryPointJsonProperty;

/**
* The list of all format properties (including `task.formatProperty`) that should be marked as
* processed once the taksk has been completed, because they point to the format-path that will be
* processed as part of the task.
*/
formatPropertiesToMarkAsProcessed: EntryPointJsonProperty[];

/** Whether to also process typings for this entry-point as part of the task. */
processDts: boolean;
}
Expand Down
14 changes: 8 additions & 6 deletions packages/compiler-cli/ngcc/src/main.ts
Expand Up @@ -117,14 +117,15 @@ export function mainNgcc(
let processDts = !hasProcessedTypings;

for (const formatProperty of propertiesToProcess) {
tasks.push({entryPoint, formatProperty, processDts});
const formatPropertiesToMarkAsProcessed =
propertyToPropertiesToMarkAsProcessed.get(formatProperty) !;
tasks.push({entryPoint, formatProperty, formatPropertiesToMarkAsProcessed, processDts});

// Only process typings for the first property (if not already processed).
processDts = false;
}

processingMetadataPerEntryPoint.set(entryPoint.path, {
propertyToPropertiesToMarkAsProcessed,
hasProcessedTypings,
hasAnyProcessedFormat: false,
});
Expand All @@ -139,7 +140,7 @@ export function mainNgcc(
const transformer = new Transformer(fileSystem, logger);

return (task: Task) => {
const {entryPoint, formatProperty, processDts} = task;
const {entryPoint, formatProperty, formatPropertiesToMarkAsProcessed, processDts} = task;

const isCore = entryPoint.name === '@angular/core'; // Are we compiling the Angular core?
const packageJson = entryPoint.packageJson;
Expand Down Expand Up @@ -171,7 +172,7 @@ export function mainNgcc(
logger.info(`Compiling ${entryPoint.name} : ${formatProperty} as ${format}`);

const transformedFiles = transformer.transform(bundle);
fileWriter.writeBundle(bundle, transformedFiles, formatProperty);
fileWriter.writeBundle(bundle, transformedFiles, formatPropertiesToMarkAsProcessed);

onTaskCompleted(task, TaskProcessingOutcome.Processed);
};
Expand All @@ -180,14 +181,15 @@ export function mainNgcc(
// The function for actually planning and getting the work done.
const executeFn: ExecuteFn = (analyzeFn: AnalyzeFn, createCompileFn: CreateCompileFn) => {
const {processingMetadataPerEntryPoint, tasks} = analyzeFn();
const compile = createCompileFn(({entryPoint, formatProperty, processDts}, outcome) => {
const compile = createCompileFn((task, outcome) => {
const {entryPoint, formatPropertiesToMarkAsProcessed, processDts} = task;
const processingMeta = processingMetadataPerEntryPoint.get(entryPoint.path) !;
processingMeta.hasAnyProcessedFormat = true;

if (outcome === TaskProcessingOutcome.Processed) {
const packageJsonPath = fileSystem.resolve(entryPoint.path, 'package.json');
const propsToMarkAsProcessed: (EntryPointJsonProperty | 'typings')[] =
processingMeta.propertyToPropertiesToMarkAsProcessed.get(formatProperty) !;
[...formatPropertiesToMarkAsProcessed];

if (processDts) {
processingMeta.hasProcessedTypings = true;
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/ngcc/src/writing/file_writer.ts
Expand Up @@ -16,5 +16,5 @@ import {FileToWrite} from '../rendering/utils';
export interface FileWriter {
writeBundle(
bundle: EntryPointBundle, transformedFiles: FileToWrite[],
formatProperty: EntryPointJsonProperty): void;
formatProperties: EntryPointJsonProperty[]): void;
}
Expand Up @@ -21,7 +21,7 @@ export class InPlaceFileWriter implements FileWriter {

writeBundle(
_bundle: EntryPointBundle, transformedFiles: FileToWrite[],
_formatProperty?: EntryPointJsonProperty) {
_formatProperties?: EntryPointJsonProperty[]) {
transformedFiles.forEach(file => this.writeFileAndBackup(file));
}

Expand Down
Expand Up @@ -27,13 +27,13 @@ const NGCC_DIRECTORY = '__ivy_ngcc__';
export class NewEntryPointFileWriter extends InPlaceFileWriter {
writeBundle(
bundle: EntryPointBundle, transformedFiles: FileToWrite[],
formatProperty: EntryPointJsonProperty) {
formatProperties: EntryPointJsonProperty[]) {
// The new folder is at the root of the overall package
const entryPoint = bundle.entryPoint;
const ngccFolder = join(entryPoint.package, NGCC_DIRECTORY);
this.copyBundle(bundle, entryPoint.package, ngccFolder);
transformedFiles.forEach(file => this.writeFile(file, entryPoint.package, ngccFolder));
this.updatePackageJson(entryPoint, formatProperty, ngccFolder);
this.updatePackageJson(entryPoint, formatProperties, ngccFolder);
}

protected copyBundle(
Expand Down Expand Up @@ -63,12 +63,16 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
}

protected updatePackageJson(
entryPoint: EntryPoint, formatProperty: EntryPointJsonProperty, ngccFolder: AbsoluteFsPath) {
const formatPath = join(entryPoint.path, entryPoint.packageJson[formatProperty] !);
const newFormatPath = join(ngccFolder, relative(entryPoint.package, formatPath));
const newFormatProperty = formatProperty + '_ivy_ngcc';
(entryPoint.packageJson as any)[newFormatProperty] = relative(entryPoint.path, newFormatPath);
entryPoint: EntryPoint, formatProperties: EntryPointJsonProperty[],
ngccFolder: AbsoluteFsPath) {
for (const formatProperty of formatProperties) {
const formatPath = join(entryPoint.path, entryPoint.packageJson[formatProperty] !);
const newFormatPath = join(ngccFolder, relative(entryPoint.package, formatPath));
const newFormatProperty = formatProperty + '_ivy_ngcc';
(entryPoint.packageJson as any)[newFormatProperty] = relative(entryPoint.path, newFormatPath);
}

this.fs.writeFile(
join(entryPoint.path, 'package.json'), JSON.stringify(entryPoint.packageJson));
join(entryPoint.path, 'package.json'), JSON.stringify(entryPoint.packageJson, null, 2));
}
}
22 changes: 22 additions & 0 deletions packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts
Expand Up @@ -382,6 +382,28 @@ runInEachFileSystem(() => {
.toMatch(ANGULAR_CORE_IMPORT_REGEX);
expect(fs.exists(_(`/node_modules/@angular/common/common.d.ts.__ivy_ngcc_bak`))).toBe(true);
});

it('should update `package.json` for all matching format properties', () => {
mainNgcc({
basePath: '/node_modules/@angular/core',
createNewEntryPointFormats: true,
propertiesToConsider: ['fesm2015', 'fesm5'],
});

const pkg: any = loadPackage('@angular/core');

// `es2015` is an alias of `fesm2015`.
expect(pkg.fesm2015).toEqual('./fesm2015/core.js');
expect(pkg.es2015).toEqual('./fesm2015/core.js');
expect(pkg.fesm2015_ivy_ngcc).toEqual('__ivy_ngcc__/fesm2015/core.js');
expect(pkg.es2015_ivy_ngcc).toEqual('__ivy_ngcc__/fesm2015/core.js');

// `module` is an alias of `fesm5`.
expect(pkg.fesm5).toEqual('./fesm5/core.js');
expect(pkg.module).toEqual('./fesm5/core.js');
expect(pkg.fesm5_ivy_ngcc).toEqual('__ivy_ngcc__/fesm5/core.js');
expect(pkg.module_ivy_ngcc).toEqual('__ivy_ngcc__/fesm5/core.js');
});
});

describe('logger', () => {
Expand Down

0 comments on commit 366c3ea

Please sign in to comment.