perf(ngcc): read dependencies from entry-point manifest (#36486)
Previously, even if an entry-point did not need to be processed, ngcc would always parse the files of the entry-point to compute its dependencies. This can take a lot of time for large node_modules. Now these dependencies are cached in the entry-point manifest, and read from there rather than computing them every time. See https://github.com/angular/angular/issues/36414\#issuecomment-608401834 FW-2047 PR Close #36486
This commit is contained in:
parent
4aa4e6fd03
commit
a185efbd60
|
@ -6,6 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
|
import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
|
||||||
|
import {EntryPoint} from '../packages/entry_point';
|
||||||
import {resolveFileWithPostfixes} from '../utils';
|
import {resolveFileWithPostfixes} from '../utils';
|
||||||
|
|
||||||
import {ModuleResolver} from './module_resolver';
|
import {ModuleResolver} from './module_resolver';
|
||||||
|
@ -21,6 +22,11 @@ export interface DependencyInfo {
|
||||||
deepImports: Set<AbsoluteFsPath>;
|
deepImports: Set<AbsoluteFsPath>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EntryPointWithDependencies {
|
||||||
|
entryPoint: EntryPoint;
|
||||||
|
depInfo: DependencyInfo;
|
||||||
|
}
|
||||||
|
|
||||||
export function createDependencyInfo(): DependencyInfo {
|
export function createDependencyInfo(): DependencyInfo {
|
||||||
return {dependencies: new Set(), missing: new Set(), deepImports: new Set()};
|
return {dependencies: new Set(), missing: new Set(), deepImports: new Set()};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {NgccConfiguration} from '../packages/configuration';
|
||||||
import {EntryPoint, EntryPointFormat, getEntryPointFormat, SUPPORTED_FORMAT_PROPERTIES} from '../packages/entry_point';
|
import {EntryPoint, EntryPointFormat, getEntryPointFormat, SUPPORTED_FORMAT_PROPERTIES} from '../packages/entry_point';
|
||||||
import {PartiallyOrderedList} from '../utils';
|
import {PartiallyOrderedList} from '../utils';
|
||||||
|
|
||||||
import {createDependencyInfo, DependencyHost, DependencyInfo} from './dependency_host';
|
import {createDependencyInfo, DependencyHost, EntryPointWithDependencies} from './dependency_host';
|
||||||
|
|
||||||
const builtinNodeJsModules = new Set<string>(require('module').builtinModules);
|
const builtinNodeJsModules = new Set<string>(require('module').builtinModules);
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ export class DependencyResolver {
|
||||||
* @param target If provided, only return entry-points depended on by this entry-point.
|
* @param target If provided, only return entry-points depended on by this entry-point.
|
||||||
* @returns the result of sorting the entry points by dependency.
|
* @returns the result of sorting the entry points by dependency.
|
||||||
*/
|
*/
|
||||||
sortEntryPointsByDependency(entryPoints: EntryPoint[], target?: EntryPoint):
|
sortEntryPointsByDependency(entryPoints: EntryPointWithDependencies[], target?: EntryPoint):
|
||||||
SortedEntryPointsInfo {
|
SortedEntryPointsInfo {
|
||||||
const {invalidEntryPoints, ignoredDependencies, graph} =
|
const {invalidEntryPoints, ignoredDependencies, graph} =
|
||||||
this.computeDependencyGraph(entryPoints);
|
this.computeDependencyGraph(entryPoints);
|
||||||
|
@ -120,18 +120,21 @@ export class DependencyResolver {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getEntryPointDependencies(entryPoint: EntryPoint): DependencyInfo {
|
getEntryPointWithDependencies(entryPoint: EntryPoint): EntryPointWithDependencies {
|
||||||
const formatInfo = this.getEntryPointFormatInfo(entryPoint);
|
const dependencies = createDependencyInfo();
|
||||||
const host = this.hosts[formatInfo.format];
|
if (entryPoint.compiledByAngular) {
|
||||||
if (!host) {
|
// Only bother to compute dependencies of entry-points that have been compiled by Angular
|
||||||
throw new Error(
|
const formatInfo = this.getEntryPointFormatInfo(entryPoint);
|
||||||
`Could not find a suitable format for computing dependencies of entry-point: '${
|
const host = this.hosts[formatInfo.format];
|
||||||
entryPoint.path}'.`);
|
if (!host) {
|
||||||
|
throw new Error(
|
||||||
|
`Could not find a suitable format for computing dependencies of entry-point: '${
|
||||||
|
entryPoint.path}'.`);
|
||||||
|
}
|
||||||
|
host.collectDependencies(formatInfo.path, dependencies);
|
||||||
|
this.typingsHost.collectDependencies(entryPoint.typings, dependencies);
|
||||||
}
|
}
|
||||||
const depInfo = createDependencyInfo();
|
return {entryPoint, depInfo: dependencies};
|
||||||
host.collectDependencies(formatInfo.path, depInfo);
|
|
||||||
this.typingsHost.collectDependencies(entryPoint.typings, depInfo);
|
|
||||||
return depInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,20 +143,18 @@ export class DependencyResolver {
|
||||||
* The graph only holds entry-points that ngcc cares about and whose dependencies
|
* The graph only holds entry-points that ngcc cares about and whose dependencies
|
||||||
* (direct and transitive) all exist.
|
* (direct and transitive) all exist.
|
||||||
*/
|
*/
|
||||||
private computeDependencyGraph(entryPoints: EntryPoint[]): DependencyGraph {
|
private computeDependencyGraph(entryPoints: EntryPointWithDependencies[]): DependencyGraph {
|
||||||
const invalidEntryPoints: InvalidEntryPoint[] = [];
|
const invalidEntryPoints: InvalidEntryPoint[] = [];
|
||||||
const ignoredDependencies: IgnoredDependency[] = [];
|
const ignoredDependencies: IgnoredDependency[] = [];
|
||||||
const graph = new DepGraph<EntryPoint>();
|
const graph = new DepGraph<EntryPoint>();
|
||||||
|
|
||||||
const angularEntryPoints = entryPoints.filter(entryPoint => entryPoint.compiledByAngular);
|
const angularEntryPoints = entryPoints.filter(e => e.entryPoint.compiledByAngular);
|
||||||
|
|
||||||
// Add the Angular compiled entry points to the graph as nodes
|
// Add the Angular compiled entry points to the graph as nodes
|
||||||
angularEntryPoints.forEach(entryPoint => graph.addNode(entryPoint.path, entryPoint));
|
angularEntryPoints.forEach(e => graph.addNode(e.entryPoint.path, e.entryPoint));
|
||||||
|
|
||||||
// Now add the dependencies between them
|
// Now add the dependencies between them
|
||||||
angularEntryPoints.forEach(entryPoint => {
|
angularEntryPoints.forEach(({entryPoint, depInfo: {dependencies, missing, deepImports}}) => {
|
||||||
const {dependencies, missing, deepImports} = this.getEntryPointDependencies(entryPoint);
|
|
||||||
|
|
||||||
const missingDependencies = Array.from(missing).filter(dep => !builtinNodeJsModules.has(dep));
|
const missingDependencies = Array.from(missing).filter(dep => !builtinNodeJsModules.has(dep));
|
||||||
|
|
||||||
if (missingDependencies.length > 0 && !entryPoint.ignoreMissingDependencies) {
|
if (missingDependencies.length > 0 && !entryPoint.ignoreMissingDependencies) {
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
|
import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
|
||||||
|
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
|
||||||
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
|
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
|
||||||
import {Logger} from '../logging/logger';
|
import {Logger} from '../logging/logger';
|
||||||
import {NgccConfiguration} from '../packages/configuration';
|
import {NgccConfiguration} from '../packages/configuration';
|
||||||
import {EntryPoint, getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from '../packages/entry_point';
|
import {getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from '../packages/entry_point';
|
||||||
import {EntryPointManifest} from '../packages/entry_point_manifest';
|
import {EntryPointManifest} from '../packages/entry_point_manifest';
|
||||||
import {PathMappings} from '../utils';
|
import {PathMappings} from '../utils';
|
||||||
import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
|
import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
|
||||||
|
@ -32,11 +33,11 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
* all package entry-points.
|
* all package entry-points.
|
||||||
*/
|
*/
|
||||||
findEntryPoints(): SortedEntryPointsInfo {
|
findEntryPoints(): SortedEntryPointsInfo {
|
||||||
const unsortedEntryPoints: EntryPoint[] = [];
|
const unsortedEntryPoints: EntryPointWithDependencies[] = [];
|
||||||
for (const basePath of this.basePaths) {
|
for (const basePath of this.basePaths) {
|
||||||
const entryPoints = this.entryPointManifest.readEntryPointsUsingManifest(basePath) ||
|
const entryPoints = this.entryPointManifest.readEntryPointsUsingManifest(basePath) ||
|
||||||
this.walkBasePathForPackages(basePath);
|
this.walkBasePathForPackages(basePath);
|
||||||
unsortedEntryPoints.push(...entryPoints);
|
entryPoints.forEach(e => unsortedEntryPoints.push(e));
|
||||||
}
|
}
|
||||||
return this.resolver.sortEntryPointsByDependency(unsortedEntryPoints);
|
return this.resolver.sortEntryPointsByDependency(unsortedEntryPoints);
|
||||||
}
|
}
|
||||||
|
@ -47,10 +48,10 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
* @param basePath The path at which to start the search
|
* @param basePath The path at which to start the search
|
||||||
* @returns an array of `EntryPoint`s that were found within `basePath`.
|
* @returns an array of `EntryPoint`s that were found within `basePath`.
|
||||||
*/
|
*/
|
||||||
walkBasePathForPackages(basePath: AbsoluteFsPath): EntryPoint[] {
|
walkBasePathForPackages(basePath: AbsoluteFsPath): EntryPointWithDependencies[] {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`No manifest found for ${basePath} so walking the directories for entry-points.`);
|
`No manifest found for ${basePath} so walking the directories for entry-points.`);
|
||||||
const entryPoints: EntryPoint[] = trackDuration(
|
const entryPoints = trackDuration(
|
||||||
() => this.walkDirectoryForPackages(basePath),
|
() => this.walkDirectoryForPackages(basePath),
|
||||||
duration => this.logger.debug(`Walking ${basePath} for entry-points took ${duration}s.`));
|
duration => this.logger.debug(`Walking ${basePath} for entry-points took ${duration}s.`));
|
||||||
this.entryPointManifest.writeEntryPointManifest(basePath, entryPoints);
|
this.entryPointManifest.writeEntryPointManifest(basePath, entryPoints);
|
||||||
|
@ -64,7 +65,7 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
* @param sourceDirectory An absolute path to the root directory where searching begins.
|
* @param sourceDirectory An absolute path to the root directory where searching begins.
|
||||||
* @returns an array of `EntryPoint`s that were found within `sourceDirectory`.
|
* @returns an array of `EntryPoint`s that were found within `sourceDirectory`.
|
||||||
*/
|
*/
|
||||||
walkDirectoryForPackages(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
|
walkDirectoryForPackages(sourceDirectory: AbsoluteFsPath): EntryPointWithDependencies[] {
|
||||||
// Try to get a primary entry point from this directory
|
// Try to get a primary entry point from this directory
|
||||||
const primaryEntryPoint =
|
const primaryEntryPoint =
|
||||||
getEntryPointInfo(this.fs, this.config, this.logger, sourceDirectory, sourceDirectory);
|
getEntryPointInfo(this.fs, this.config, this.logger, sourceDirectory, sourceDirectory);
|
||||||
|
@ -76,15 +77,15 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const entryPoints: EntryPoint[] = [];
|
const entryPoints: EntryPointWithDependencies[] = [];
|
||||||
if (primaryEntryPoint !== NO_ENTRY_POINT) {
|
if (primaryEntryPoint !== NO_ENTRY_POINT) {
|
||||||
entryPoints.push(primaryEntryPoint);
|
entryPoints.push(this.resolver.getEntryPointWithDependencies(primaryEntryPoint));
|
||||||
this.collectSecondaryEntryPoints(
|
this.collectSecondaryEntryPoints(
|
||||||
entryPoints, sourceDirectory, sourceDirectory, this.fs.readdir(sourceDirectory));
|
entryPoints, sourceDirectory, sourceDirectory, this.fs.readdir(sourceDirectory));
|
||||||
|
|
||||||
// Also check for any nested node_modules in this package but only if at least one of the
|
// Also check for any nested node_modules in this package but only if at least one of the
|
||||||
// entry-points was compiled by Angular.
|
// entry-points was compiled by Angular.
|
||||||
if (entryPoints.some(e => e.compiledByAngular)) {
|
if (entryPoints.some(e => e.entryPoint.compiledByAngular)) {
|
||||||
const nestedNodeModulesPath = this.fs.join(sourceDirectory, 'node_modules');
|
const nestedNodeModulesPath = this.fs.join(sourceDirectory, 'node_modules');
|
||||||
if (this.fs.exists(nestedNodeModulesPath)) {
|
if (this.fs.exists(nestedNodeModulesPath)) {
|
||||||
entryPoints.push(...this.walkDirectoryForPackages(nestedNodeModulesPath));
|
entryPoints.push(...this.walkDirectoryForPackages(nestedNodeModulesPath));
|
||||||
|
@ -125,8 +126,8 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
* @param paths The paths contained in the current `directory`.
|
* @param paths The paths contained in the current `directory`.
|
||||||
*/
|
*/
|
||||||
private collectSecondaryEntryPoints(
|
private collectSecondaryEntryPoints(
|
||||||
entryPoints: EntryPoint[], packagePath: AbsoluteFsPath, directory: AbsoluteFsPath,
|
entryPoints: EntryPointWithDependencies[], packagePath: AbsoluteFsPath,
|
||||||
paths: PathSegment[]): void {
|
directory: AbsoluteFsPath, paths: PathSegment[]): void {
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
if (isIgnorablePath(path)) {
|
if (isIgnorablePath(path)) {
|
||||||
// Ignore hidden files, node_modules and ngcc directory
|
// Ignore hidden files, node_modules and ngcc directory
|
||||||
|
@ -153,7 +154,7 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||||
const subEntryPoint =
|
const subEntryPoint =
|
||||||
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, possibleEntryPointPath);
|
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, possibleEntryPointPath);
|
||||||
if (subEntryPoint !== NO_ENTRY_POINT && subEntryPoint !== INCOMPATIBLE_ENTRY_POINT) {
|
if (subEntryPoint !== NO_ENTRY_POINT && subEntryPoint !== INCOMPATIBLE_ENTRY_POINT) {
|
||||||
entryPoints.push(subEntryPoint);
|
entryPoints.push(this.resolver.getEntryPointWithDependencies(subEntryPoint));
|
||||||
isEntryPoint = true;
|
isEntryPoint = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {AbsoluteFsPath, FileSystem, join, PathSegment, relative, relativeFrom} from '../../../src/ngtsc/file_system';
|
import {AbsoluteFsPath, FileSystem, join, PathSegment, relative, relativeFrom} from '../../../src/ngtsc/file_system';
|
||||||
|
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
|
||||||
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
|
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
|
||||||
import {Logger} from '../logging/logger';
|
import {Logger} from '../logging/logger';
|
||||||
import {hasBeenProcessed} from '../packages/build_marker';
|
import {hasBeenProcessed} from '../packages/build_marker';
|
||||||
|
@ -25,7 +26,7 @@ import {getBasePaths} from './utils';
|
||||||
*/
|
*/
|
||||||
export class TargetedEntryPointFinder implements EntryPointFinder {
|
export class TargetedEntryPointFinder implements EntryPointFinder {
|
||||||
private unprocessedPaths: AbsoluteFsPath[] = [];
|
private unprocessedPaths: AbsoluteFsPath[] = [];
|
||||||
private unsortedEntryPoints = new Map<AbsoluteFsPath, EntryPoint>();
|
private unsortedEntryPoints = new Map<AbsoluteFsPath, EntryPointWithDependencies>();
|
||||||
private basePaths = getBasePaths(this.logger, this.basePath, this.pathMappings);
|
private basePaths = getBasePaths(this.logger, this.basePath, this.pathMappings);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -40,7 +41,7 @@ export class TargetedEntryPointFinder implements EntryPointFinder {
|
||||||
}
|
}
|
||||||
const targetEntryPoint = this.unsortedEntryPoints.get(this.targetPath);
|
const targetEntryPoint = this.unsortedEntryPoints.get(this.targetPath);
|
||||||
const entryPoints = this.resolver.sortEntryPointsByDependency(
|
const entryPoints = this.resolver.sortEntryPointsByDependency(
|
||||||
Array.from(this.unsortedEntryPoints.values()), targetEntryPoint);
|
Array.from(this.unsortedEntryPoints.values()), targetEntryPoint?.entryPoint);
|
||||||
|
|
||||||
const invalidTarget =
|
const invalidTarget =
|
||||||
entryPoints.invalidEntryPoints.find(i => i.entryPoint.path === this.targetPath);
|
entryPoints.invalidEntryPoints.find(i => i.entryPoint.path === this.targetPath);
|
||||||
|
@ -82,9 +83,9 @@ export class TargetedEntryPointFinder implements EntryPointFinder {
|
||||||
if (entryPoint === null || !entryPoint.compiledByAngular) {
|
if (entryPoint === null || !entryPoint.compiledByAngular) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.unsortedEntryPoints.set(entryPoint.path, entryPoint);
|
const entryPointWithDeps = this.resolver.getEntryPointWithDependencies(entryPoint);
|
||||||
const deps = this.resolver.getEntryPointDependencies(entryPoint);
|
this.unsortedEntryPoints.set(entryPoint.path, entryPointWithDeps);
|
||||||
deps.dependencies.forEach(dep => {
|
entryPointWithDeps.depInfo.dependencies.forEach(dep => {
|
||||||
if (!this.unsortedEntryPoints.has(dep)) {
|
if (!this.unsortedEntryPoints.has(dep)) {
|
||||||
this.unprocessedPaths.push(dep);
|
this.unprocessedPaths.push(dep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
*/
|
*/
|
||||||
import {createHash} from 'crypto';
|
import {createHash} from 'crypto';
|
||||||
|
|
||||||
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
|
import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
|
||||||
|
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
|
||||||
import {Logger} from '../logging/logger';
|
import {Logger} from '../logging/logger';
|
||||||
|
|
||||||
import {NGCC_VERSION} from './build_marker';
|
import {NGCC_VERSION} from './build_marker';
|
||||||
import {NgccConfiguration} from './configuration';
|
import {NgccConfiguration} from './configuration';
|
||||||
import {EntryPoint, getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from './entry_point';
|
import {getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from './entry_point';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages reading and writing a manifest file that contains a list of all the entry-points that
|
* Manages reading and writing a manifest file that contains a list of all the entry-points that
|
||||||
|
@ -40,7 +41,7 @@ export class EntryPointManifest {
|
||||||
* @returns an array of entry-point information for all entry-points found below the given
|
* @returns an array of entry-point information for all entry-points found below the given
|
||||||
* `basePath` or `null` if the manifest was out of date.
|
* `basePath` or `null` if the manifest was out of date.
|
||||||
*/
|
*/
|
||||||
readEntryPointsUsingManifest(basePath: AbsoluteFsPath): EntryPoint[]|null {
|
readEntryPointsUsingManifest(basePath: AbsoluteFsPath): EntryPointWithDependencies[]|null {
|
||||||
try {
|
try {
|
||||||
if (this.fs.basename(basePath) !== 'node_modules') {
|
if (this.fs.basename(basePath) !== 'node_modules') {
|
||||||
return null;
|
return null;
|
||||||
|
@ -67,8 +68,9 @@ export class EntryPointManifest {
|
||||||
basePath} so loading entry-point information directly.`);
|
basePath} so loading entry-point information directly.`);
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
const entryPoints: EntryPoint[] = [];
|
const entryPoints: EntryPointWithDependencies[] = [];
|
||||||
for (const [packagePath, entryPointPath] of entryPointPaths) {
|
for (const [packagePath, entryPointPath, dependencyPaths, missingPaths, deepImportPaths] of
|
||||||
|
entryPointPaths) {
|
||||||
const result =
|
const result =
|
||||||
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, entryPointPath);
|
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, entryPointPath);
|
||||||
if (result === NO_ENTRY_POINT || result === INCOMPATIBLE_ENTRY_POINT) {
|
if (result === NO_ENTRY_POINT || result === INCOMPATIBLE_ENTRY_POINT) {
|
||||||
|
@ -76,7 +78,14 @@ export class EntryPointManifest {
|
||||||
manifestPath} contained an invalid pair of package paths: [${packagePath}, ${
|
manifestPath} contained an invalid pair of package paths: [${packagePath}, ${
|
||||||
entryPointPath}]`);
|
entryPointPath}]`);
|
||||||
} else {
|
} else {
|
||||||
entryPoints.push(result);
|
entryPoints.push({
|
||||||
|
entryPoint: result,
|
||||||
|
depInfo: {
|
||||||
|
dependencies: new Set(dependencyPaths),
|
||||||
|
missing: new Set(missingPaths),
|
||||||
|
deepImports: new Set(deepImportPaths),
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const duration = Math.round((Date.now() - startTime) / 100) / 10;
|
const duration = Math.round((Date.now() - startTime) / 100) / 10;
|
||||||
|
@ -99,7 +108,8 @@ export class EntryPointManifest {
|
||||||
* @param basePath The path where the manifest file is to be written.
|
* @param basePath The path where the manifest file is to be written.
|
||||||
* @param entryPoints A collection of entry-points to record in the manifest.
|
* @param entryPoints A collection of entry-points to record in the manifest.
|
||||||
*/
|
*/
|
||||||
writeEntryPointManifest(basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): void {
|
writeEntryPointManifest(basePath: AbsoluteFsPath, entryPoints: EntryPointWithDependencies[]):
|
||||||
|
void {
|
||||||
if (this.fs.basename(basePath) !== 'node_modules') {
|
if (this.fs.basename(basePath) !== 'node_modules') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +122,14 @@ export class EntryPointManifest {
|
||||||
ngccVersion: NGCC_VERSION,
|
ngccVersion: NGCC_VERSION,
|
||||||
configFileHash: this.config.hash,
|
configFileHash: this.config.hash,
|
||||||
lockFileHash: lockFileHash,
|
lockFileHash: lockFileHash,
|
||||||
entryPointPaths: entryPoints.map(entryPoint => [entryPoint.package, entryPoint.path]),
|
entryPointPaths: entryPoints.map(
|
||||||
|
e =>
|
||||||
|
[e.entryPoint.package,
|
||||||
|
e.entryPoint.path,
|
||||||
|
Array.from(e.depInfo.dependencies),
|
||||||
|
Array.from(e.depInfo.missing),
|
||||||
|
Array.from(e.depInfo.deepImports),
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
this.fs.writeFile(this.getEntryPointManifestPath(basePath), JSON.stringify(manifest));
|
this.fs.writeFile(this.getEntryPointManifestPath(basePath), JSON.stringify(manifest));
|
||||||
}
|
}
|
||||||
|
@ -143,7 +160,7 @@ export class EntryPointManifest {
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
export class InvalidatingEntryPointManifest extends EntryPointManifest {
|
export class InvalidatingEntryPointManifest extends EntryPointManifest {
|
||||||
readEntryPointsUsingManifest(basePath: AbsoluteFsPath): EntryPoint[]|null {
|
readEntryPointsUsingManifest(_basePath: AbsoluteFsPath): EntryPointWithDependencies[]|null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,5 +172,8 @@ export interface EntryPointManifestFile {
|
||||||
ngccVersion: string;
|
ngccVersion: string;
|
||||||
configFileHash: string;
|
configFileHash: string;
|
||||||
lockFileHash: string;
|
lockFileHash: string;
|
||||||
entryPointPaths: Array<[AbsoluteFsPath, AbsoluteFsPath]>;
|
entryPointPaths: Array<[
|
||||||
|
AbsoluteFsPath, AbsoluteFsPath, AbsoluteFsPath[], (AbsoluteFsPath | PathSegment)[],
|
||||||
|
AbsoluteFsPath[]
|
||||||
|
]>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {DepGraph} from 'dependency-graph';
|
||||||
|
|
||||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relativeFrom} from '../../../src/ngtsc/file_system';
|
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relativeFrom} from '../../../src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||||
import {DependencyInfo} from '../../src/dependencies/dependency_host';
|
import {DependencyInfo, EntryPointWithDependencies} from '../../src/dependencies/dependency_host';
|
||||||
import {DependencyResolver, SortedEntryPointsInfo} from '../../src/dependencies/dependency_resolver';
|
import {DependencyResolver, SortedEntryPointsInfo} from '../../src/dependencies/dependency_resolver';
|
||||||
import {DtsDependencyHost} from '../../src/dependencies/dts_dependency_host';
|
import {DtsDependencyHost} from '../../src/dependencies/dts_dependency_host';
|
||||||
import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host';
|
import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host';
|
||||||
|
@ -131,7 +131,8 @@ runInEachFileSystem(() => {
|
||||||
.and.callFake(createFakeComputeDependencies(dependencies));
|
.and.callFake(createFakeComputeDependencies(dependencies));
|
||||||
spyOn(dtsHost, 'collectDependencies')
|
spyOn(dtsHost, 'collectDependencies')
|
||||||
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
||||||
const result = resolver.sortEntryPointsByDependency([fifth, first, fourth, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [fifth, first, fourth, second, third]));
|
||||||
expect(result.entryPoints).toEqual([fifth, fourth, third, second, first]);
|
expect(result.entryPoints).toEqual([fifth, fourth, third, second, first]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -144,7 +145,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/first/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
[_('/first/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
||||||
[_('/second/sub/index.d.ts')]: {resolved: [], missing: []},
|
[_('/second/sub/index.d.ts')]: {resolved: [], missing: []},
|
||||||
}));
|
}));
|
||||||
const result = resolver.sortEntryPointsByDependency([first, second]);
|
const result =
|
||||||
|
resolver.sortEntryPointsByDependency(getEntryPointsWithDeps(resolver, [first, second]));
|
||||||
expect(result.entryPoints).toEqual([second]);
|
expect(result.entryPoints).toEqual([second]);
|
||||||
expect(result.invalidEntryPoints).toEqual([
|
expect(result.invalidEntryPoints).toEqual([
|
||||||
{entryPoint: first, missingDependencies: [_('/missing')]},
|
{entryPoint: first, missingDependencies: [_('/missing')]},
|
||||||
|
@ -163,7 +165,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/third/index.d.ts')]: {resolved: [], missing: []},
|
[_('/third/index.d.ts')]: {resolved: [], missing: []},
|
||||||
}));
|
}));
|
||||||
// Note that we will process `first` before `second`, which has the missing dependency.
|
// Note that we will process `first` before `second`, which has the missing dependency.
|
||||||
const result = resolver.sortEntryPointsByDependency([first, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [first, second, third]));
|
||||||
expect(result.entryPoints).toEqual([third]);
|
expect(result.entryPoints).toEqual([third]);
|
||||||
expect(result.invalidEntryPoints).toEqual([
|
expect(result.invalidEntryPoints).toEqual([
|
||||||
{entryPoint: second, missingDependencies: [_('/missing')]},
|
{entryPoint: second, missingDependencies: [_('/missing')]},
|
||||||
|
@ -183,7 +186,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/third/index.d.ts')]: {resolved: [], missing: []},
|
[_('/third/index.d.ts')]: {resolved: [], missing: []},
|
||||||
}));
|
}));
|
||||||
// Note that we will process `first` after `second`, which has the missing dependency.
|
// Note that we will process `first` after `second`, which has the missing dependency.
|
||||||
const result = resolver.sortEntryPointsByDependency([second, first, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [second, first, third]));
|
||||||
expect(result.entryPoints).toEqual([third]);
|
expect(result.entryPoints).toEqual([third]);
|
||||||
expect(result.invalidEntryPoints).toEqual([
|
expect(result.invalidEntryPoints).toEqual([
|
||||||
{entryPoint: second, missingDependencies: [_('/missing')]},
|
{entryPoint: second, missingDependencies: [_('/missing')]},
|
||||||
|
@ -202,7 +206,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/sixth/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
[_('/sixth/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
||||||
}));
|
}));
|
||||||
// Note that we will process `first` after `second`, which has the missing dependency.
|
// Note that we will process `first` after `second`, which has the missing dependency.
|
||||||
const result = resolver.sortEntryPointsByDependency([sixthIgnoreMissing, first]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [sixthIgnoreMissing, first]));
|
||||||
expect(result.entryPoints).toEqual([sixthIgnoreMissing, first]);
|
expect(result.entryPoints).toEqual([sixthIgnoreMissing, first]);
|
||||||
expect(result.invalidEntryPoints).toEqual([]);
|
expect(result.invalidEntryPoints).toEqual([]);
|
||||||
});
|
});
|
||||||
|
@ -218,7 +223,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/second/sub/index.d.ts')]: {resolved: [first.path], missing: []},
|
[_('/second/sub/index.d.ts')]: {resolved: [first.path], missing: []},
|
||||||
[_('/sixth/index.d.ts')]: {resolved: [second.path], missing: []},
|
[_('/sixth/index.d.ts')]: {resolved: [second.path], missing: []},
|
||||||
}));
|
}));
|
||||||
const result = resolver.sortEntryPointsByDependency([first, second, sixthIgnoreMissing]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [first, second, sixthIgnoreMissing]));
|
||||||
// sixth has no missing dependencies, but it has _invalid_ dependencies, so it's not
|
// sixth has no missing dependencies, but it has _invalid_ dependencies, so it's not
|
||||||
// compiled.
|
// compiled.
|
||||||
expect(result.entryPoints).toEqual([]);
|
expect(result.entryPoints).toEqual([]);
|
||||||
|
@ -235,7 +241,8 @@ runInEachFileSystem(() => {
|
||||||
[_('/second/sub/index.d.ts')]: {resolved: [], missing: [_('/missing2')]},
|
[_('/second/sub/index.d.ts')]: {resolved: [], missing: [_('/missing2')]},
|
||||||
[_('/third/index.d.ts')]: {resolved: [first.path, second.path], missing: []},
|
[_('/third/index.d.ts')]: {resolved: [first.path, second.path], missing: []},
|
||||||
}));
|
}));
|
||||||
const result = resolver.sortEntryPointsByDependency([first, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [first, second, third]));
|
||||||
expect(result.entryPoints).toEqual([]);
|
expect(result.entryPoints).toEqual([]);
|
||||||
expect(result.invalidEntryPoints).toEqual([
|
expect(result.invalidEntryPoints).toEqual([
|
||||||
{entryPoint: first, missingDependencies: [_('/missing1')]},
|
{entryPoint: first, missingDependencies: [_('/missing1')]},
|
||||||
|
@ -251,7 +258,8 @@ runInEachFileSystem(() => {
|
||||||
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
||||||
[_('/first/index.d.ts')]: {resolved: [], missing: []},
|
[_('/first/index.d.ts')]: {resolved: [], missing: []},
|
||||||
}));
|
}));
|
||||||
const result = resolver.sortEntryPointsByDependency([first]);
|
const result =
|
||||||
|
resolver.sortEntryPointsByDependency(getEntryPointsWithDeps(resolver, [first]));
|
||||||
expect(result.entryPoints).toEqual([first]);
|
expect(result.entryPoints).toEqual([first]);
|
||||||
expect(logger.logs.warn).toEqual([[
|
expect(logger.logs.warn).toEqual([[
|
||||||
`Entry point 'first' contains deep imports into '${
|
`Entry point 'first' contains deep imports into '${
|
||||||
|
@ -290,7 +298,8 @@ runInEachFileSystem(() => {
|
||||||
typings: _('/project/node_modules/test-package/index.d.ts'),
|
typings: _('/project/node_modules/test-package/index.d.ts'),
|
||||||
} as EntryPoint;
|
} as EntryPoint;
|
||||||
|
|
||||||
const result = resolver.sortEntryPointsByDependency([testEntryPoint]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [testEntryPoint]));
|
||||||
expect(result.entryPoints).toEqual([testEntryPoint]);
|
expect(result.entryPoints).toEqual([testEntryPoint]);
|
||||||
expect(logger.logs.warn).toEqual([[
|
expect(logger.logs.warn).toEqual([[
|
||||||
`Entry point 'test-package' contains deep imports into '${
|
`Entry point 'test-package' contains deep imports into '${
|
||||||
|
@ -299,14 +308,15 @@ runInEachFileSystem(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error if the entry point does not have a suitable format', () => {
|
it('should error if the entry point does not have a suitable format', () => {
|
||||||
expect(() => resolver.sortEntryPointsByDependency([
|
expect(() => resolver.sortEntryPointsByDependency(getEntryPointsWithDeps(resolver, [
|
||||||
{path: '/first', packageJson: {}, compiledByAngular: true} as EntryPoint
|
{path: '/first', packageJson: {}, compiledByAngular: true} as EntryPoint
|
||||||
])).toThrowError(`There is no appropriate source code format in '/first' entry-point.`);
|
]))).toThrowError(`There is no appropriate source code format in '/first' entry-point.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error if there is no appropriate DependencyHost for the given formats', () => {
|
it('should error if there is no appropriate DependencyHost for the given formats', () => {
|
||||||
resolver = new DependencyResolver(fs, new MockLogger(), config, {esm2015: host}, host);
|
resolver = new DependencyResolver(fs, new MockLogger(), config, {esm2015: host}, host);
|
||||||
expect(() => resolver.sortEntryPointsByDependency([first]))
|
expect(
|
||||||
|
() => resolver.sortEntryPointsByDependency(getEntryPointsWithDeps(resolver, [first])))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
`Could not find a suitable format for computing dependencies of entry-point: '${
|
`Could not find a suitable format for computing dependencies of entry-point: '${
|
||||||
first.path}'.`);
|
first.path}'.`);
|
||||||
|
@ -317,7 +327,8 @@ runInEachFileSystem(() => {
|
||||||
.and.callFake(createFakeComputeDependencies(dependencies));
|
.and.callFake(createFakeComputeDependencies(dependencies));
|
||||||
spyOn(dtsHost, 'collectDependencies')
|
spyOn(dtsHost, 'collectDependencies')
|
||||||
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
||||||
const result = resolver.sortEntryPointsByDependency([fifth, first, fourth, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [fifth, first, fourth, second, third]));
|
||||||
expect(result.ignoredDependencies).toEqual([
|
expect(result.ignoredDependencies).toEqual([
|
||||||
{entryPoint: first, dependencyPath: _('/ignored-1')},
|
{entryPoint: first, dependencyPath: _('/ignored-1')},
|
||||||
{entryPoint: third, dependencyPath: _('/ignored-2')},
|
{entryPoint: third, dependencyPath: _('/ignored-2')},
|
||||||
|
@ -329,7 +340,8 @@ runInEachFileSystem(() => {
|
||||||
.and.callFake(createFakeComputeDependencies(dependencies));
|
.and.callFake(createFakeComputeDependencies(dependencies));
|
||||||
spyOn(dtsHost, 'collectDependencies')
|
spyOn(dtsHost, 'collectDependencies')
|
||||||
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
||||||
const result = resolver.sortEntryPointsByDependency([fifth, first, fourth, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [fifth, first, fourth, second, third]));
|
||||||
|
|
||||||
expect(result.graph).toEqual(jasmine.any(DepGraph));
|
expect(result.graph).toEqual(jasmine.any(DepGraph));
|
||||||
expect(result.graph.size()).toBe(5);
|
expect(result.graph.size()).toBe(5);
|
||||||
|
@ -341,7 +353,7 @@ runInEachFileSystem(() => {
|
||||||
.and.callFake(createFakeComputeDependencies(dependencies));
|
.and.callFake(createFakeComputeDependencies(dependencies));
|
||||||
spyOn(dtsHost, 'collectDependencies')
|
spyOn(dtsHost, 'collectDependencies')
|
||||||
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
||||||
const entryPoints = [fifth, first, fourth, second, third];
|
const entryPoints = getEntryPointsWithDeps(resolver, [fifth, first, fourth, second, third]);
|
||||||
let sorted: SortedEntryPointsInfo;
|
let sorted: SortedEntryPointsInfo;
|
||||||
|
|
||||||
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
||||||
|
@ -363,7 +375,7 @@ runInEachFileSystem(() => {
|
||||||
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
||||||
[_('/first/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
[_('/first/index.d.ts')]: {resolved: [], missing: [_('/missing')]},
|
||||||
}));
|
}));
|
||||||
const entryPoints = [first];
|
const entryPoints = getEntryPointsWithDeps(resolver, [first]);
|
||||||
let sorted: SortedEntryPointsInfo;
|
let sorted: SortedEntryPointsInfo;
|
||||||
|
|
||||||
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
||||||
|
@ -379,7 +391,7 @@ runInEachFileSystem(() => {
|
||||||
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
spyOn(dtsHost, 'collectDependencies').and.callFake(createFakeComputeDependencies({
|
||||||
[_('/first/index.d.ts')]: {resolved: [], missing: ['fs']},
|
[_('/first/index.d.ts')]: {resolved: [], missing: ['fs']},
|
||||||
}));
|
}));
|
||||||
const entryPoints = [first];
|
const entryPoints = getEntryPointsWithDeps(resolver, [first]);
|
||||||
let sorted: SortedEntryPointsInfo;
|
let sorted: SortedEntryPointsInfo;
|
||||||
|
|
||||||
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
sorted = resolver.sortEntryPointsByDependency(entryPoints, first);
|
||||||
|
@ -400,7 +412,8 @@ runInEachFileSystem(() => {
|
||||||
.and.callFake(createFakeComputeDependencies(dependencies));
|
.and.callFake(createFakeComputeDependencies(dependencies));
|
||||||
spyOn(dtsHost, 'collectDependencies')
|
spyOn(dtsHost, 'collectDependencies')
|
||||||
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
.and.callFake(createFakeComputeDependencies(dtsDependencies));
|
||||||
const result = resolver.sortEntryPointsByDependency([fifth, first, fourth, second, third]);
|
const result = resolver.sortEntryPointsByDependency(
|
||||||
|
getEntryPointsWithDeps(resolver, [fifth, first, fourth, second, third]));
|
||||||
expect(result.entryPoints).toEqual([fifth, fourth, third, second, first]);
|
expect(result.entryPoints).toEqual([fifth, fourth, third, second, first]);
|
||||||
|
|
||||||
expect(esm5Host.collectDependencies)
|
expect(esm5Host.collectDependencies)
|
||||||
|
@ -449,7 +462,7 @@ runInEachFileSystem(() => {
|
||||||
[_('/second/sub/index.d.ts')]: {resolved: [], missing: [_('/missing2')]},
|
[_('/second/sub/index.d.ts')]: {resolved: [], missing: [_('/missing2')]},
|
||||||
[_('/third/index.d.ts')]: {resolved: [second.path], missing: []},
|
[_('/third/index.d.ts')]: {resolved: [second.path], missing: []},
|
||||||
}));
|
}));
|
||||||
const entryPoints = [first, second, third];
|
const entryPoints = getEntryPointsWithDeps(resolver, [first, second, third]);
|
||||||
const sorted = resolver.sortEntryPointsByDependency(entryPoints);
|
const sorted = resolver.sortEntryPointsByDependency(entryPoints);
|
||||||
expect(sorted.entryPoints).toEqual([first]);
|
expect(sorted.entryPoints).toEqual([first]);
|
||||||
expect(sorted.invalidEntryPoints).toEqual([
|
expect(sorted.invalidEntryPoints).toEqual([
|
||||||
|
@ -469,6 +482,11 @@ runInEachFileSystem(() => {
|
||||||
return {dependencies, missing, deepImports};
|
return {dependencies, missing, deepImports};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEntryPointsWithDeps(
|
||||||
|
resolver: DependencyResolver, entryPoints: EntryPoint[]): EntryPointWithDependencies[] {
|
||||||
|
return entryPoints.map(entryPoint => resolver.getEntryPointWithDependencies(entryPoint));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1107,7 +1107,12 @@ runInEachFileSystem(() => {
|
||||||
// had removed earlier.
|
// had removed earlier.
|
||||||
manifest = JSON.parse(fs.readFile(_('/node_modules/__ngcc_entry_points__.json')));
|
manifest = JSON.parse(fs.readFile(_('/node_modules/__ngcc_entry_points__.json')));
|
||||||
expect(manifest.entryPointPaths).toContain([
|
expect(manifest.entryPointPaths).toContain([
|
||||||
_('/node_modules/@angular/common'), _('/node_modules/@angular/common/testing')
|
_('/node_modules/@angular/common'), _('/node_modules/@angular/common/testing'),
|
||||||
|
[
|
||||||
|
_('/node_modules/@angular/core'), _('/node_modules/@angular/common'),
|
||||||
|
_('/node_modules/rxjs')
|
||||||
|
],
|
||||||
|
[], []
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
*/
|
*/
|
||||||
import {createHash} from 'crypto';
|
import {createHash} from 'crypto';
|
||||||
|
|
||||||
import {absoluteFrom, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
|
import {absoluteFrom, FileSystem, getFileSystem, relativeFrom} from '../../../src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||||
import {loadTestFiles} from '../../../test/helpers';
|
import {loadTestFiles} from '../../../test/helpers';
|
||||||
|
import {EntryPointWithDependencies} from '../../src/dependencies/dependency_host';
|
||||||
import {NGCC_VERSION} from '../../src/packages/build_marker';
|
import {NGCC_VERSION} from '../../src/packages/build_marker';
|
||||||
import {NgccConfiguration} from '../../src/packages/configuration';
|
import {NgccConfiguration} from '../../src/packages/configuration';
|
||||||
import {EntryPoint} from '../../src/packages/entry_point';
|
|
||||||
import {EntryPointManifest, EntryPointManifestFile} from '../../src/packages/entry_point_manifest';
|
import {EntryPointManifest, EntryPointManifestFile} from '../../src/packages/entry_point_manifest';
|
||||||
import {MockLogger} from '../helpers/mock_logger';
|
import {MockLogger} from '../helpers/mock_logger';
|
||||||
|
|
||||||
|
@ -129,22 +129,48 @@ runInEachFileSystem(() => {
|
||||||
]);
|
]);
|
||||||
manifestFile.entryPointPaths.push([
|
manifestFile.entryPointPaths.push([
|
||||||
_Abs('/project/node_modules/some_package'),
|
_Abs('/project/node_modules/some_package'),
|
||||||
_Abs('/project/node_modules/some_package/valid_entry_point')
|
_Abs('/project/node_modules/some_package/valid_entry_point'),
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/other_package_1'),
|
||||||
|
_Abs('/project/node_modules/other_package_2'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/missing_1'),
|
||||||
|
relativeFrom('missing_2'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/deep/import/path'),
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
fs.writeFile(
|
fs.writeFile(
|
||||||
_Abs('/project/node_modules/__ngcc_entry_points__.json'), JSON.stringify(manifestFile));
|
_Abs('/project/node_modules/__ngcc_entry_points__.json'), JSON.stringify(manifestFile));
|
||||||
const entryPoints = manifest.readEntryPointsUsingManifest(_Abs('/project/node_modules'));
|
const entryPoints = manifest.readEntryPointsUsingManifest(_Abs('/project/node_modules'));
|
||||||
expect(entryPoints).toEqual([{
|
expect(entryPoints).toEqual([{
|
||||||
name: 'some_package/valid_entry_point',
|
entryPoint: {
|
||||||
packageJson: jasmine.any(Object),
|
name: 'some_package/valid_entry_point',
|
||||||
package: _Abs('/project/node_modules/some_package'),
|
packageJson: jasmine.any(Object),
|
||||||
path: _Abs('/project/node_modules/some_package/valid_entry_point'),
|
package: _Abs('/project/node_modules/some_package'),
|
||||||
typings:
|
path: _Abs('/project/node_modules/some_package/valid_entry_point'),
|
||||||
_Abs('/project/node_modules/some_package/valid_entry_point/valid_entry_point.d.ts'),
|
typings:
|
||||||
compiledByAngular: true,
|
_Abs('/project/node_modules/some_package/valid_entry_point/valid_entry_point.d.ts'),
|
||||||
ignoreMissingDependencies: false,
|
compiledByAngular: true,
|
||||||
generateDeepReexports: false,
|
ignoreMissingDependencies: false,
|
||||||
} as any]);
|
generateDeepReexports: false,
|
||||||
|
} as any,
|
||||||
|
depInfo: {
|
||||||
|
dependencies: new Set([
|
||||||
|
_Abs('/project/node_modules/other_package_1'),
|
||||||
|
_Abs('/project/node_modules/other_package_2'),
|
||||||
|
]),
|
||||||
|
missing: new Set([
|
||||||
|
_Abs('/project/node_modules/missing_1'),
|
||||||
|
relativeFrom('missing_2'),
|
||||||
|
]),
|
||||||
|
deepImports: new Set([
|
||||||
|
_Abs('/project/node_modules/deep/import/path'),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return null if any of the entry-points are not valid', () => {
|
it('should return null if any of the entry-points are not valid', () => {
|
||||||
|
@ -152,7 +178,7 @@ runInEachFileSystem(() => {
|
||||||
fs.writeFile(_Abs('/project/yarn.lock'), 'LOCK FILE CONTENTS');
|
fs.writeFile(_Abs('/project/yarn.lock'), 'LOCK FILE CONTENTS');
|
||||||
manifestFile.entryPointPaths.push([
|
manifestFile.entryPointPaths.push([
|
||||||
_Abs('/project/node_modules/some_package'),
|
_Abs('/project/node_modules/some_package'),
|
||||||
_Abs('/project/node_modules/some_package/valid_entry_point')
|
_Abs('/project/node_modules/some_package/valid_entry_point'), [], [], []
|
||||||
]);
|
]);
|
||||||
fs.writeFile(
|
fs.writeFile(
|
||||||
_Abs('/project/node_modules/__ngcc_entry_points__.json'), JSON.stringify(manifestFile));
|
_Abs('/project/node_modules/__ngcc_entry_points__.json'), JSON.stringify(manifestFile));
|
||||||
|
@ -223,14 +249,36 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should write the package path and entry-point path of each entry-point provided', () => {
|
it('should write the package path and entry-point path of each entry-point provided', () => {
|
||||||
fs.writeFile(_Abs('/project/package-lock.json'), 'LOCK FILE CONTENTS');
|
fs.writeFile(_Abs('/project/package-lock.json'), 'LOCK FILE CONTENTS');
|
||||||
const entryPoint1 = {
|
const entryPoint1: EntryPointWithDependencies = {
|
||||||
package: _Abs('/project/node_modules/package-1/'),
|
entryPoint: {
|
||||||
path: _Abs('/project/node_modules/package-1/'),
|
package: _Abs('/project/node_modules/package-1/'),
|
||||||
} as unknown as EntryPoint;
|
path: _Abs('/project/node_modules/package-1/'),
|
||||||
const entryPoint2 = {
|
} as any,
|
||||||
package: _Abs('/project/node_modules/package-2/'),
|
depInfo: {
|
||||||
path: _Abs('/project/node_modules/package-2/entry-point'),
|
dependencies: new Set([
|
||||||
} as unknown as EntryPoint;
|
_Abs('/project/node_modules/other_package_1'),
|
||||||
|
_Abs('/project/node_modules/other_package_2'),
|
||||||
|
]),
|
||||||
|
missing: new Set(),
|
||||||
|
deepImports: new Set()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const entryPoint2: EntryPointWithDependencies = {
|
||||||
|
entryPoint: {
|
||||||
|
package: _Abs('/project/node_modules/package-2/'),
|
||||||
|
path: _Abs('/project/node_modules/package-2/entry-point'),
|
||||||
|
} as any,
|
||||||
|
depInfo: {
|
||||||
|
dependencies: new Set(),
|
||||||
|
missing: new Set([
|
||||||
|
_Abs('/project/node_modules/missing_1'),
|
||||||
|
relativeFrom('missing_2'),
|
||||||
|
]),
|
||||||
|
deepImports: new Set([
|
||||||
|
_Abs('/project/node_modules/deep/import/path'),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
};
|
||||||
manifest.writeEntryPointManifest(_Abs('/project/node_modules'), [entryPoint1, entryPoint2]);
|
manifest.writeEntryPointManifest(_Abs('/project/node_modules'), [entryPoint1, entryPoint2]);
|
||||||
const file: EntryPointManifestFile =
|
const file: EntryPointManifestFile =
|
||||||
JSON.parse(fs.readFile(_Abs('/project/node_modules/__ngcc_entry_points__.json')));
|
JSON.parse(fs.readFile(_Abs('/project/node_modules/__ngcc_entry_points__.json')));
|
||||||
|
@ -238,10 +286,24 @@ runInEachFileSystem(() => {
|
||||||
[
|
[
|
||||||
_Abs('/project/node_modules/package-1/'),
|
_Abs('/project/node_modules/package-1/'),
|
||||||
_Abs('/project/node_modules/package-1/'),
|
_Abs('/project/node_modules/package-1/'),
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/other_package_1'),
|
||||||
|
_Abs('/project/node_modules/other_package_2'),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
_Abs('/project/node_modules/package-2/'),
|
_Abs('/project/node_modules/package-2/'),
|
||||||
_Abs('/project/node_modules/package-2/entry-point'),
|
_Abs('/project/node_modules/package-2/entry-point'),
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/missing_1'),
|
||||||
|
relativeFrom('missing_2'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
_Abs('/project/node_modules/deep/import/path'),
|
||||||
|
],
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue