From 57e15fc08be50e30eba7abe914308838a7cdad80 Mon Sep 17 00:00:00 2001 From: JoostK Date: Sat, 27 Jul 2019 21:37:04 +0200 Subject: [PATCH] fix(ivy): ngcc - do not consider builtin NodeJS modules as missing (#31872) ngcc analyzes the dependency structure of the entrypoints it needs to process, as the compilation of entrypoints is ordering sensitive: any dependent upon entrypoint must be compiled before its dependees. As part of the analysis of the dependency graph, it is detected when a dependency of entrypoint is not installed, in which case that entrypoint will be marked as ignored. For libraries that work with Angular Universal to run in NodeJS, imports into builtin NodeJS modules can be present. ngcc's dependency analyzer can only resolve imports within the TypeScript compilation, which builtin modules are not part of. Therefore, such imports would erroneously cause the entrypoint to become ignored. This commit fixes the problem by taking the NodeJS builtins into account when dealing with missing imports. Fixes #31522 PR Close #31872 --- .../ngcc/src/dependencies/dependency_resolver.ts | 8 ++++++-- .../test/dependencies/dependency_resolver_spec.ts | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts index 316dc2c474..e2c404c9c2 100644 --- a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts +++ b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts @@ -12,6 +12,8 @@ import {Logger} from '../logging/logger'; import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointFormat} from '../packages/entry_point'; import {DependencyHost, DependencyInfo} from './dependency_host'; +const builtinNodeJsModules = new Set(require('module').builtinModules); + /** * Holds information about entry points that are removed because * they have dependencies that are missing (directly or transitively). @@ -128,10 +130,12 @@ export class DependencyResolver { angularEntryPoints.forEach(entryPoint => { const {dependencies, missing, deepImports} = this.getEntryPointDependencies(entryPoint); - if (missing.size > 0) { + const missingDependencies = Array.from(missing).filter(dep => !builtinNodeJsModules.has(dep)); + + if (missingDependencies.length > 0) { // This entry point has dependencies that are missing // so remove it from the graph. - removeNodes(entryPoint, Array.from(missing)); + removeNodes(entryPoint, missingDependencies); } else { dependencies.forEach(dependencyPath => { if (!graph.hasNode(entryPoint.path)) { diff --git a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts index 6d395632d7..b5645f0aa5 100644 --- a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts +++ b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts @@ -192,6 +192,19 @@ runInEachFileSystem(() => { expect(sorted.invalidEntryPoints[0].missingDependencies).toEqual(['/missing']); }); + it('should not consider builtin NodeJS modules as missing dependency', () => { + spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({ + [_('/first/index.js')]: {resolved: [], missing: ['fs']}, + })); + const entryPoints = [first]; + let sorted: SortedEntryPointsInfo; + + sorted = resolver.sortEntryPointsByDependency(entryPoints, first); + expect(sorted.entryPoints).toEqual([first]); + expect(sorted.invalidEntryPoints).toEqual([]); + expect(sorted.ignoredDependencies).toEqual([]); + }); + it('should use the appropriate DependencyHost for each entry-point', () => { const esm5Host = new EsmDependencyHost(fs, moduleResolver); const esm2015Host = new EsmDependencyHost(fs, moduleResolver);