fix(ivy): ngcc - capture entry-points in top-level path-mapped folders (#31027)

The `EntryPointFinder` computes the base paths to consider
when searching for entry-points. When there are `pathMappings`
provided it works out the best top level base-paths that cover all
the potential mappings.

If this computed basePath happens to coincide with an entry-point
path itself then we were missing it.

Now we check for an entry-point even at the base-path itself.

Related to https://github.com/angular/angular-cli/pull/14755

PR Close #31027
This commit is contained in:
Pete Bacon Darwin 2019-06-13 12:20:02 +01:00 committed by Andrew Kushnir
parent cc0bd11a5e
commit 0c3bb6a731
2 changed files with 52 additions and 13 deletions

View File

@ -70,7 +70,12 @@ export class EntryPointFinder {
* @param sourceDirectory An absolute path to the root directory where searching begins.
*/
private walkDirectoryForEntryPoints(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
const entryPoints: EntryPoint[] = [];
const entryPoints = this.getEntryPointsForPackage(sourceDirectory);
if (entryPoints.length > 0) {
// The `sourceDirectory` is an entry-point itself so no need to search its sub-directories.
return entryPoints;
}
this.fs
.readdir(sourceDirectory)
// Not interested in hidden files
@ -86,16 +91,12 @@ export class EntryPointFinder {
// Either the directory is a potential package or a namespace containing packages (e.g
// `@angular`).
const packagePath = AbsoluteFsPath.join(sourceDirectory, p);
if (p.startsWith('@')) {
entryPoints.push(...this.walkDirectoryForEntryPoints(packagePath));
} else {
entryPoints.push(...this.getEntryPointsForPackage(packagePath));
entryPoints.push(...this.walkDirectoryForEntryPoints(packagePath));
// Also check for any nested node_modules in this package
const nestedNodeModulesPath = AbsoluteFsPath.join(packagePath, 'node_modules');
if (this.fs.exists(nestedNodeModulesPath)) {
entryPoints.push(...this.walkDirectoryForEntryPoints(nestedNodeModulesPath));
}
// Also check for any nested node_modules in this package
const nestedNodeModulesPath = AbsoluteFsPath.join(packagePath, 'node_modules');
if (this.fs.exists(nestedNodeModulesPath)) {
entryPoints.push(...this.walkDirectoryForEntryPoints(nestedNodeModulesPath));
}
});
return entryPoints;
@ -111,11 +112,14 @@ export class EntryPointFinder {
// Try to get an entry point from the top level package directory
const topLevelEntryPoint = getEntryPointInfo(this.fs, this.logger, packagePath, packagePath);
if (topLevelEntryPoint !== null) {
entryPoints.push(topLevelEntryPoint);
// If there is no primary entry-point then exit
if (topLevelEntryPoint === null) {
return [];
}
// Now search all the directories of this package for possible entry points
// Otherwise store it and search for secondary entry-points
entryPoints.push(topLevelEntryPoint);
this.walkDirectory(packagePath, subdir => {
const subEntryPoint = getEntryPointInfo(this.fs, this.logger, packagePath, subdir);
if (subEntryPoint !== null) {

View File

@ -52,6 +52,21 @@ describe('findEntryPoints()', () => {
]);
});
it('should find entry-points via `pathMappings', () => {
const {entryPoints} = finder.findEntryPoints(
_('/pathMappings/node_modules'), undefined,
{baseUrl: _('/pathMappings'), paths: {'my-lib': ['dist/my-lib']}});
const entryPointPaths = entryPoints.map(x => [x.package, x.path]);
expect(entryPointPaths).toEqual([
[_('/pathMappings/dist/my-lib'), _('/pathMappings/dist/my-lib')],
[_('/pathMappings/dist/my-lib'), _('/pathMappings/dist/my-lib/sub-lib')],
[
_('/pathMappings/node_modules/@angular/common'),
_('/pathMappings/node_modules/@angular/common')
],
]);
});
it('should return an empty array if there are no packages', () => {
const {entryPoints} = finder.findEntryPoints(_('/no_packages'));
expect(entryPoints).toEqual([]);
@ -105,6 +120,26 @@ describe('findEntryPoints()', () => {
},
},
},
'/pathMappings': {
'dist': {
'my-lib': {
'package.json': createPackageJson('my-lib'),
'my-lib.metadata.json': 'metadata info',
'sub-lib': {
'package.json': createPackageJson('sub-lib'),
'sub-lib.metadata.json': 'metadata info',
},
},
},
'node_modules': {
'@angular': {
'common': {
'package.json': createPackageJson('common'),
'common.metadata.json': 'metadata info',
},
},
}
},
'/namespaced': {
'@angular': {
'common': {