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

@ -9,8 +9,9 @@ import {AbsoluteFsPath, FileSystem, join, resolve} from '../../../src/ngtsc/file
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
import {Logger} from '../logging/logger';
import {NgccConfiguration} from '../packages/configuration';
import {EntryPoint, getEntryPointInfo} from '../packages/entry_point';
import {EntryPoint, INVALID_ENTRY_POINT, NO_ENTRY_POINT, getEntryPointInfo} from '../packages/entry_point';
import {PathMappings} from '../utils';
import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
import {EntryPointFinder} from './interface';
import {getBasePaths} from './utils';
@ -40,10 +41,24 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
* The function will recurse into directories that start with `@...`, e.g. `@angular/...`.
* @param sourceDirectory An absolute path to the root directory where searching begins.
*/
private walkDirectoryForEntryPoints(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
walkDirectoryForEntryPoints(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
const entryPoints = this.getEntryPointsForPackage(sourceDirectory);
if (entryPoints === null) {
return [];
}
if (entryPoints.length > 0) {
// The `sourceDirectory` is an entry-point itself so no need to search its sub-directories.
// The `sourceDirectory` is an entry point itself so no need to search its sub-directories.
// Also check for any nested node_modules in this package but only if it was compiled by
// Angular.
// It is unlikely that a non Angular entry point has a dependency on an Angular library.
if (entryPoints.some(e => e.compiledByAngular)) {
const nestedNodeModulesPath = this.fs.join(sourceDirectory, 'node_modules');
if (this.fs.exists(nestedNodeModulesPath)) {
entryPoints.push(...this.walkDirectoryForEntryPoints(nestedNodeModulesPath));
}
}
return entryPoints;
}
@ -52,23 +67,16 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
// Not interested in hidden files
.filter(p => !p.startsWith('.'))
// Ignore node_modules
.filter(p => p !== 'node_modules')
.filter(p => p !== 'node_modules' && p !== NGCC_DIRECTORY)
// Only interested in directories (and only those that are not symlinks)
.filter(p => {
const stat = this.fs.lstat(resolve(sourceDirectory, p));
return stat.isDirectory() && !stat.isSymbolicLink();
})
.forEach(p => {
// Either the directory is a potential package or a namespace containing packages (e.g
// `@angular`).
// Package is a potential namespace containing packages (e.g `@angular`).
const packagePath = join(sourceDirectory, p);
entryPoints.push(...this.walkDirectoryForEntryPoints(packagePath));
// Also check for any nested node_modules in this package
const nestedNodeModulesPath = join(packagePath, 'node_modules');
if (this.fs.exists(nestedNodeModulesPath)) {
entryPoints.push(...this.walkDirectoryForEntryPoints(nestedNodeModulesPath));
}
});
return entryPoints;
}
@ -76,9 +84,9 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
/**
* Recurse the folder structure looking for all the entry points
* @param packagePath The absolute path to an npm package that may contain entry points
* @returns An array of entry points that were discovered.
* @returns An array of entry points that were discovered or null when it's not a valid entrypoint
*/
private getEntryPointsForPackage(packagePath: AbsoluteFsPath): EntryPoint[] {
private getEntryPointsForPackage(packagePath: AbsoluteFsPath): EntryPoint[]|null {
const entryPoints: EntryPoint[] = [];
// Try to get an entry point from the top level package directory
@ -86,20 +94,30 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, packagePath);
// If there is no primary entry-point then exit
if (topLevelEntryPoint === null) {
if (topLevelEntryPoint === NO_ENTRY_POINT) {
return [];
}
if (topLevelEntryPoint === INVALID_ENTRY_POINT) {
return null;
}
// Otherwise store it and search for secondary entry-points
entryPoints.push(topLevelEntryPoint);
this.walkDirectory(packagePath, packagePath, (path, isDirectory) => {
if (!path.endsWith('.js') && !isDirectory) {
return false;
}
// If the path is a JS file then strip its extension and see if we can match an entry-point.
const possibleEntryPointPath = isDirectory ? path : stripJsExtension(path);
const subEntryPoint =
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, possibleEntryPointPath);
if (subEntryPoint !== null) {
entryPoints.push(subEntryPoint);
if (subEntryPoint === NO_ENTRY_POINT || subEntryPoint === INVALID_ENTRY_POINT) {
return false;
}
entryPoints.push(subEntryPoint);
return true;
});
return entryPoints;
@ -113,26 +131,25 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
*/
private walkDirectory(
packagePath: AbsoluteFsPath, dir: AbsoluteFsPath,
fn: (path: AbsoluteFsPath, isDirectory: boolean) => void) {
fn: (path: AbsoluteFsPath, isDirectory: boolean) => boolean) {
return this.fs
.readdir(dir)
// Not interested in hidden files
.filter(path => !path.startsWith('.'))
// Ignore node_modules
.filter(path => path !== 'node_modules')
.map(path => resolve(dir, path))
.filter(path => path !== 'node_modules' && path !== NGCC_DIRECTORY)
.forEach(path => {
const stat = this.fs.lstat(path);
const absolutePath = resolve(dir, path);
const stat = this.fs.lstat(absolutePath);
if (stat.isSymbolicLink()) {
// We are not interested in symbolic links
return;
}
fn(path, stat.isDirectory());
if (stat.isDirectory()) {
this.walkDirectory(packagePath, path, fn);
const containsEntryPoint = fn(absolutePath, stat.isDirectory());
if (containsEntryPoint) {
this.walkDirectory(packagePath, absolutePath, fn);
}
});
}

View File

@ -10,7 +10,7 @@ import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/depende
import {Logger} from '../logging/logger';
import {hasBeenProcessed} from '../packages/build_marker';
import {NgccConfiguration} from '../packages/configuration';
import {EntryPoint, EntryPointJsonProperty, getEntryPointInfo} from '../packages/entry_point';
import {EntryPoint, EntryPointJsonProperty, INVALID_ENTRY_POINT, NO_ENTRY_POINT, getEntryPointInfo} from '../packages/entry_point';
import {PathMappings} from '../utils';
import {EntryPointFinder} from './interface';
import {getBasePaths} from './utils';
@ -78,20 +78,26 @@ export class TargetedEntryPointFinder implements EntryPointFinder {
private processNextPath(): void {
const path = this.unprocessedPaths.shift() !;
const entryPoint = this.getEntryPoint(path);
if (entryPoint !== null && entryPoint.compiledByAngular) {
this.unsortedEntryPoints.set(entryPoint.path, entryPoint);
const deps = this.resolver.getEntryPointDependencies(entryPoint);
deps.dependencies.forEach(dep => {
if (!this.unsortedEntryPoints.has(dep)) {
this.unprocessedPaths.push(dep);
}
});
if (entryPoint === null || !entryPoint.compiledByAngular) {
return;
}
this.unsortedEntryPoints.set(entryPoint.path, entryPoint);
const deps = this.resolver.getEntryPointDependencies(entryPoint);
deps.dependencies.forEach(dep => {
if (!this.unsortedEntryPoints.has(dep)) {
this.unprocessedPaths.push(dep);
}
});
}
private getEntryPoint(entryPointPath: AbsoluteFsPath): EntryPoint|null {
const packagePath = this.computePackagePath(entryPointPath);
return getEntryPointInfo(this.fs, this.config, this.logger, packagePath, entryPointPath);
const entryPoint =
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, entryPointPath);
if (entryPoint === NO_ENTRY_POINT || entryPoint === INVALID_ENTRY_POINT) {
return null;
}
return entryPoint;
}
/**

View File

@ -75,41 +75,77 @@ export type EntryPointJsonProperty = Exclude<PackageJsonFormatProperties, 'types
export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
['fesm2015', 'fesm5', 'es2015', 'esm2015', 'esm5', 'main', 'module'];
/**
* The path does not represent an entry-point:
* * there is no package.json at the path and there is no config to force an entry-point
* * or the entrypoint is `ignored` by a config.
*/
export const NO_ENTRY_POINT = 'no-entry-point';
/**
* The path has a package.json, but it is not a valid entry-point for ngcc processing.
*/
export const INVALID_ENTRY_POINT = 'invalid-entry-point';
/**
* The result of calling `getEntryPointInfo()`.
*
* This will be an `EntryPoint` object if an Angular entry-point was identified;
* Otherwise it will be a flag indicating one of:
* * NO_ENTRY_POINT - the path is not an entry-point or ngcc is configured to ignore it
* * INVALID_ENTRY_POINT - the path was a non-processable entry-point that should be searched
* for sub-entry-points
*/
export type GetEntryPointResult = EntryPoint | typeof INVALID_ENTRY_POINT | typeof NO_ENTRY_POINT;
/**
* Try to create an entry-point from the given paths and properties.
*
* @param packagePath the absolute path to the containing npm package
* @param entryPointPath the absolute path to the potential entry-point.
* @returns An entry-point if it is valid, `null` otherwise.
* @returns
* - An entry-point if it is valid.
* - `undefined` when there is no package.json at the path and there is no config to force an
* entry-point or the entrypoint is `ignored`.
* - `null` there is a package.json but it is not a valid Angular compiled entry-point.
*/
export function getEntryPointInfo(
fs: FileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): EntryPoint|null {
entryPointPath: AbsoluteFsPath): GetEntryPointResult {
const packageJsonPath = resolve(entryPointPath, 'package.json');
const packageVersion = getPackageVersion(fs, packageJsonPath);
const entryPointConfig =
config.getConfig(packagePath, packageVersion).entryPoints[entryPointPath];
if (entryPointConfig === undefined && !fs.exists(packageJsonPath)) {
return null;
const hasConfig = entryPointConfig !== undefined;
if (!hasConfig && !fs.exists(packageJsonPath)) {
// No package.json and no config
return NO_ENTRY_POINT;
}
if (entryPointConfig !== undefined && entryPointConfig.ignore === true) {
return null;
if (hasConfig && entryPointConfig.ignore === true) {
// Explicitly ignored
return NO_ENTRY_POINT;
}
const loadedEntryPointPackageJson =
loadEntryPointPackage(fs, logger, packageJsonPath, entryPointConfig !== undefined);
const entryPointPackageJson = mergeConfigAndPackageJson(
loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath);
const loadedEntryPointPackageJson = loadEntryPointPackage(fs, logger, packageJsonPath, hasConfig);
const entryPointPackageJson = hasConfig ?
mergeConfigAndPackageJson(
loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath) :
loadedEntryPointPackageJson;
if (entryPointPackageJson === null) {
return null;
// package.json exists but could not be parsed and there was no redeeming config
return INVALID_ENTRY_POINT;
}
// We must have a typings property
const typings = entryPointPackageJson.typings || entryPointPackageJson.types ||
guessTypingsFromPackageJson(fs, entryPointPath, entryPointPackageJson);
if (typeof typings !== 'string') {
return null;
// Missing the required `typings` property
return INVALID_ENTRY_POINT;
}
// An entry-point is assumed to be compiled by Angular if there is either:
@ -198,22 +234,13 @@ function isUmdModule(fs: FileSystem, sourceFilePath: AbsoluteFsPath): boolean {
}
function mergeConfigAndPackageJson(
entryPointPackageJson: EntryPointPackageJson | null,
entryPointConfig: NgccEntryPointConfig | undefined, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): EntryPointPackageJson|null {
entryPointPackageJson: EntryPointPackageJson | null, entryPointConfig: NgccEntryPointConfig,
packagePath: AbsoluteFsPath, entryPointPath: AbsoluteFsPath): EntryPointPackageJson {
if (entryPointPackageJson !== null) {
if (entryPointConfig === undefined) {
return entryPointPackageJson;
} else {
return {...entryPointPackageJson, ...entryPointConfig.override};
}
return {...entryPointPackageJson, ...entryPointConfig.override};
} else {
if (entryPointConfig === undefined) {
return null;
} else {
const name = `${basename(packagePath)}/${relative(packagePath, entryPointPath)}`;
return {name, ...entryPointConfig.override};
}
const name = `${basename(packagePath)}/${relative(packagePath, entryPointPath)}`;
return {name, ...entryPointConfig.override};
}
}

View File

@ -136,6 +136,71 @@ runInEachFileSystem(() => {
]);
});
it('should handle try to process nested node_modules of non Angular packages', () => {
const basePath = _Abs('/nested_node_modules/node_modules');
loadTestFiles([
...createPackage(basePath, 'outer', ['inner'], false),
...createPackage(_Abs(`${basePath}/outer/node_modules`), 'inner', undefined, false),
]);
const finder = new DirectoryWalkerEntryPointFinder(
fs, config, logger, resolver, _Abs('/nested_node_modules/node_modules'), undefined);
const spy = spyOn(finder, 'walkDirectoryForEntryPoints').and.callThrough();
const {entryPoints} = finder.findEntryPoints();
expect(spy.calls.allArgs()).toEqual([
[_Abs(basePath)],
[_Abs(`${basePath}/outer`)],
]);
expect(entryPoints).toEqual([]);
});
it('should not try to process deeply nested folders of non TypeScript packages', () => {
const basePath = _Abs('/namespaced/node_modules');
loadTestFiles([
...createNonTsPackage(_Abs(`${basePath}/@schematics`), 'angular'),
{
name: _Abs(`${basePath}/@schematics/angular/src/nested/index.js`),
contents: 'index',
},
]);
const finder =
new DirectoryWalkerEntryPointFinder(fs, config, logger, resolver, basePath, undefined);
const spy = spyOn(finder, 'walkDirectoryForEntryPoints').and.callThrough();
const {entryPoints} = finder.findEntryPoints();
expect(spy.calls.allArgs()).toEqual([
[_Abs(basePath)],
[_Abs(`${basePath}/@schematics`)],
[_Abs(`${basePath}/@schematics/angular`)],
]);
expect(entryPoints).toEqual([]);
});
it('should not try to process nested node_modules of non TypeScript packages', () => {
const basePath = _Abs('/namespaced/node_modules');
loadTestFiles([
...createNonTsPackage(_Abs(`${basePath}/@schematics`), 'angular'),
...createNonTsPackage(_Abs(`${basePath}/@schematics/angular/node_modules`), 'test'),
{
name: _Abs(`${basePath}/@schematics/angular/src/nested/index.js`),
contents: 'index',
},
]);
const finder =
new DirectoryWalkerEntryPointFinder(fs, config, logger, resolver, basePath, undefined);
const spy = spyOn(finder, 'walkDirectoryForEntryPoints').and.callThrough();
const {entryPoints} = finder.findEntryPoints();
expect(spy.calls.allArgs()).toEqual([
[_Abs(basePath)],
[_Abs(`${basePath}/@schematics`)],
[_Abs(`${basePath}/@schematics/angular`)],
]);
expect(entryPoints).toEqual([]);
});
it('should handle dependencies via pathMappings', () => {
const basePath = _Abs('/path_mapped/node_modules');
@ -195,8 +260,9 @@ runInEachFileSystem(() => {
});
function createPackage(
basePath: AbsoluteFsPath, packageName: string, deps: string[] = []): TestFile[] {
return [
basePath: AbsoluteFsPath, packageName: string, deps: string[] = [],
isCompiledByAngular = true): TestFile[] {
const files: TestFile[] = [
{
name: _Abs(`${basePath}/${packageName}/package.json`),
contents: JSON.stringify({
@ -205,8 +271,29 @@ runInEachFileSystem(() => {
})
},
{
name: _Abs(`${basePath}/${packageName}/fesm2015/${packageName}.js`),
contents: deps.map((dep, i) => `import * as i${i} from '${dep}';`).join('\n'),
},
];
if (isCompiledByAngular) {
files.push({
name: _Abs(`${basePath}/${packageName}/${packageName}.metadata.json`),
contents: 'metadata info'
});
}
return files;
}
function createNonTsPackage(
basePath: AbsoluteFsPath, packageName: string, deps: string[] = []): TestFile[] {
return [
{
name: _Abs(`${basePath}/${packageName}/package.json`),
contents: JSON.stringify({
fesm2015: `./fesm2015/${packageName}.js`,
})
},
{
name: _Abs(`${basePath}/${packageName}/fesm2015/${packageName}.js`),

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',

View File

@ -9,7 +9,7 @@ import {FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_s
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadTestFiles} from '../../../test/helpers';
import {NgccConfiguration} from '../../src/packages/configuration';
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointInfo} from '../../src/packages/entry_point';
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, INVALID_ENTRY_POINT, NO_ENTRY_POINT, getEntryPointInfo} from '../../src/packages/entry_point';
import {EntryPointBundle, makeEntryPointBundle} from '../../src/packages/entry_point_bundle';
import {FileWriter} from '../../src/writing/file_writer';
import {NewEntryPointFileWriter} from '../../src/writing/new_entry_point_file_writer';
@ -103,8 +103,12 @@ runInEachFileSystem(() => {
fs = getFileSystem();
fileWriter = new NewEntryPointFileWriter(fs, new DirectPackageJsonUpdater(fs));
const config = new NgccConfiguration(fs, _('/'));
entryPoint = getEntryPointInfo(
const result = getEntryPointInfo(
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test')) !;
if (result === NO_ENTRY_POINT || result === INVALID_ENTRY_POINT) {
return fail(`Expected an entry point but got ${result}`);
}
entryPoint = result;
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
});
@ -239,8 +243,12 @@ runInEachFileSystem(() => {
fs = getFileSystem();
fileWriter = new NewEntryPointFileWriter(fs, new DirectPackageJsonUpdater(fs));
const config = new NgccConfiguration(fs, _('/'));
entryPoint = getEntryPointInfo(
const result = getEntryPointInfo(
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/a')) !;
if (result === NO_ENTRY_POINT || result === INVALID_ENTRY_POINT) {
return fail(`Expected an entry point but got ${result}`);
}
entryPoint = result;
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
});
@ -364,8 +372,12 @@ runInEachFileSystem(() => {
fs = getFileSystem();
fileWriter = new NewEntryPointFileWriter(fs, new DirectPackageJsonUpdater(fs));
const config = new NgccConfiguration(fs, _('/'));
entryPoint = getEntryPointInfo(
const result = getEntryPointInfo(
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/b')) !;
if (result === NO_ENTRY_POINT || result === INVALID_ENTRY_POINT) {
return fail(`Expected an entry point but got ${result}`);
}
entryPoint = result;
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
});