perf(ngcc): reduce directory traversing (#35756)

This reduces the time that `findEntryPoints` takes from 9701.143ms to 4177.278ms, by reducing the file operations done.

Reference: #35717

PR Close #35756
This commit is contained in:
Alan Agius
2020-03-03 09:50:15 +01:00
committed by Matias Niemelä
parent 8ef29b65ff
commit e0a35e13d5
6 changed files with 251 additions and 97 deletions

View File

@ -10,7 +10,7 @@ import {AbsoluteFsPath, FileSystem, absoluteFrom, getFileSystem} from '../../../
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadTestFiles} from '../../../test/helpers';
import {NgccConfiguration} from '../../src/packages/configuration';
import {EntryPoint, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat, getEntryPointInfo} from '../../src/packages/entry_point';
import {EntryPoint, INVALID_ENTRY_POINT, NO_ENTRY_POINT, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat, getEntryPointInfo} from '../../src/packages/entry_point';
import {MockLogger} from '../helpers/mock_logger';
runInEachFileSystem(() => {
@ -55,7 +55,7 @@ runInEachFileSystem(() => {
});
});
it('should return null if configured to ignore the specified entry-point', () => {
it('should return `NO_ENTRY_POINT` if configured to ignore the specified entry-point', () => {
loadTestFiles([
{
name: _('/project/node_modules/some_package/valid_entry_point/package.json'),
@ -75,7 +75,7 @@ runInEachFileSystem(() => {
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/valid_entry_point'));
expect(entryPoint).toBe(null);
expect(entryPoint).toBe(NO_ENTRY_POINT);
});
it('should override the properties on package.json if the entry-point is configured', () => {
@ -116,7 +116,7 @@ runInEachFileSystem(() => {
});
});
it('should return null if there is no package.json at the entry-point path', () => {
it('should return `NO_ENTRY_POINT` if there is no package.json at the entry-point path', () => {
loadTestFiles([
{
name: _(
@ -128,7 +128,7 @@ runInEachFileSystem(() => {
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/missing_package_json'));
expect(entryPoint).toBe(null);
expect(entryPoint).toBe(NO_ENTRY_POINT);
});
it('should return a configured entry-point if there is no package.json at the entry-point path',
@ -165,26 +165,27 @@ runInEachFileSystem(() => {
});
it('should return null if there is no typings or types field in the package.json', () => {
loadTestFiles([
{
name: _('/project/node_modules/some_package/missing_typings/package.json'),
contents: createPackageJson('missing_typings', {excludes: ['typings']})
},
{
name:
_('/project/node_modules/some_package/missing_typings/missing_typings.metadata.json'),
contents: 'some meta data'
},
]);
const config = new NgccConfiguration(fs, _('/project'));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/missing_typings'));
expect(entryPoint).toBe(null);
});
it('should return `INVALID_ENTRY_POINT` if there is no typings or types field in the package.json',
() => {
loadTestFiles([
{
name: _('/project/node_modules/some_package/missing_typings/package.json'),
contents: createPackageJson('missing_typings', {excludes: ['typings']})
},
{
name: _(
'/project/node_modules/some_package/missing_typings/missing_typings.metadata.json'),
contents: 'some meta data'
},
]);
const config = new NgccConfiguration(fs, _('/project'));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/missing_typings'));
expect(entryPoint).toBe(INVALID_ENTRY_POINT);
});
it('should return null if the typings or types field is not a string in the package.json',
it('should return `INVALID_ENTRY_POINT` if the typings or types field is not a string in the package.json',
() => {
loadTestFiles([
{
@ -201,7 +202,7 @@ runInEachFileSystem(() => {
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/typings_array'));
expect(entryPoint).toBe(null);
expect(entryPoint).toBe(INVALID_ENTRY_POINT);
});
for (let prop of SUPPORTED_FORMAT_PROPERTIES) {
@ -358,7 +359,7 @@ runInEachFileSystem(() => {
});
});
it('should return null if the package.json is not valid JSON', () => {
it('should return `INVALID_ENTRY_POINT` if the package.json is not valid JSON', () => {
loadTestFiles([
// package.json might not be a valid JSON
// for example, @schematics/angular contains a package.json blueprint
@ -372,7 +373,7 @@ runInEachFileSystem(() => {
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/unexpected_symbols'));
expect(entryPoint).toBe(null);
expect(entryPoint).toBe(INVALID_ENTRY_POINT);
});
});
@ -391,9 +392,13 @@ runInEachFileSystem(() => {
contents: createPackageJson('valid_entry_point')
}]);
const config = new NgccConfiguration(fs, _('/project'));
entryPoint = getEntryPointInfo(
const result = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
_('/project/node_modules/some_package/valid_entry_point')) !;
_('/project/node_modules/some_package/valid_entry_point'));
if (result === NO_ENTRY_POINT || result === INVALID_ENTRY_POINT) {
return fail(`Expected an entry point but got ${result}`);
}
entryPoint = result;
});
it('should return `esm2015` format for `fesm2015` property',