Skip to content

Commit 0093b3b

Browse files
JoostKthePunderWoman
authored andcommitted
fix(ngcc): do not compile JavaScript sources if typings-only processing is repeated (angular#41209)
The recently introduced typings-only mode in ngcc would incorrectly write compiled JavaScript files if typings-only mode was requested, in case the typings of the entry-point had already been processed in a prior run of ngcc. The corresponding format property for which the JavaScript files were written were not marked as processed, though, as the typings-only mode excluded the format property itself from being marked as processed. Consequently, subsequent runs of ngcc would not consider the entry-point to have been processed and recompile the JavaScript bundle once more, resulting in duplicate ngcc imports. Fixes angular#41198 PR Close angular#41209
1 parent 7d6db00 commit 0093b3b

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

packages/compiler-cli/ngcc/src/execution/analyze_entry_points.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,8 @@ export function getAnalyzeEntryPointsFn(
4949

5050
for (const entryPoint of entryPoints) {
5151
const packageJson = entryPoint.packageJson;
52-
const hasProcessedTypings = hasBeenProcessed(packageJson, 'typings');
5352
const {propertiesToProcess, equivalentPropertiesMap} = getPropertiesToProcess(
5453
packageJson, supportedPropertiesToConsider, compileAllFormats, typingsOnly);
55-
let processDts = hasProcessedTypings ? DtsProcessing.No :
56-
typingsOnly ? DtsProcessing.Only : DtsProcessing.Yes;
5754

5855
if (propertiesToProcess.length === 0) {
5956
// This entry-point is unprocessable (i.e. there is no format property that is of interest
@@ -64,6 +61,16 @@ export function getAnalyzeEntryPointsFn(
6461
continue;
6562
}
6663

64+
const hasProcessedTypings = hasBeenProcessed(packageJson, 'typings');
65+
if (hasProcessedTypings && typingsOnly) {
66+
// Typings for this entry-point have already been processed and we're in typings-only mode,
67+
// so no task has to be created for this entry-point.
68+
logger.debug(`Skipping ${entryPoint.name} : typings have already been processed.`);
69+
continue;
70+
}
71+
let processDts = hasProcessedTypings ? DtsProcessing.No :
72+
typingsOnly ? DtsProcessing.Only : DtsProcessing.Yes;
73+
6774
for (const formatProperty of propertiesToProcess) {
6875
if (hasBeenProcessed(entryPoint.packageJson, formatProperty)) {
6976
// The format-path which the property maps to is already processed - nothing to do.

packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,66 @@ runInEachFileSystem(() => {
13581358
expect(fs.exists(_(`/node_modules/@angular/common/common.d.ts.__ivy_ngcc_bak`))).toBe(true);
13591359
});
13601360

1361+
it('should not compile anything when typings have already been processed', () => {
1362+
let logger = new MockLogger();
1363+
mainNgcc({
1364+
basePath: '/node_modules',
1365+
propertiesToConsider: ['esm2015'],
1366+
targetEntryPointPath: '@angular/core',
1367+
typingsOnly: true,
1368+
logger,
1369+
});
1370+
expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({
1371+
typings: '0.0.0-PLACEHOLDER',
1372+
});
1373+
expect(fs.readFile(_(`/node_modules/@angular/core/esm2015/src/application_init.js`)))
1374+
.not.toMatch(ANGULAR_CORE_IMPORT_REGEX);
1375+
expect(logger.logs.debug).toContain([' Successfully compiled @angular/core : esm2015']);
1376+
1377+
// Try to process the typings for @angular/core again, now using a different format
1378+
// property, to verify that it does not process the entry-point again and that the JS
1379+
// files are still untouched.
1380+
logger = new MockLogger();
1381+
mainNgcc({
1382+
basePath: '/node_modules',
1383+
propertiesToConsider: ['main'],
1384+
targetEntryPointPath: '@angular/core',
1385+
typingsOnly: true,
1386+
logger,
1387+
});
1388+
expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({
1389+
typings: '0.0.0-PLACEHOLDER',
1390+
});
1391+
expect(fs.readFile(_(`/node_modules/@angular/core/esm2015/src/application_init.js`)))
1392+
.not.toMatch(ANGULAR_CORE_IMPORT_REGEX);
1393+
expect(logger.logs.debug).toContain([
1394+
'Skipping @angular/core : typings have already been processed.'
1395+
]);
1396+
1397+
// Now also process the typings for @angular/common to verify that its dependency on
1398+
// @angular/core, which has already been processed and will therefore be skipped, is able
1399+
// to succeed.
1400+
logger = new MockLogger();
1401+
mainNgcc({
1402+
basePath: '/node_modules',
1403+
propertiesToConsider: ['esm2015'],
1404+
targetEntryPointPath: '@angular/common',
1405+
typingsOnly: true,
1406+
logger,
1407+
});
1408+
expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({
1409+
typings: '0.0.0-PLACEHOLDER',
1410+
});
1411+
expect(fs.readFile(_(`/node_modules/@angular/core/esm2015/src/application_init.js`)))
1412+
.not.toMatch(ANGULAR_CORE_IMPORT_REGEX);
1413+
expect(fs.readFile(_(`/node_modules/@angular/common/esm2015/src/common_module.js`)))
1414+
.not.toMatch(ANGULAR_CORE_IMPORT_REGEX);
1415+
expect(logger.logs.debug).toContain([
1416+
'Skipping @angular/core : typings have already been processed.'
1417+
]);
1418+
expect(logger.logs.debug).toContain([' Successfully compiled @angular/common : esm2015']);
1419+
});
1420+
13611421
it('should cope with compiling the same entry-point multiple times with different formats',
13621422
() => {
13631423
mainNgcc({

0 commit comments

Comments
 (0)