Skip to content

Commit 9ef6b82

Browse files
committed
Merge pull request #529 from mousetraps/i521
#511, #521 npm tree fixes
2 parents f0d68f9 + 52b9c70 commit 9ef6b82

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

Nodejs/Product/Npm/SPI/AbstractNodeModules.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal abstract class AbstractNodeModules : INodeModules {
2424
private readonly IDictionary<string, IPackage> _packagesByName = new Dictionary<string, IPackage>();
2525

2626
protected virtual void AddModule(IPackage package) {
27-
if (!_packagesSorted.Contains(package) && package.Name != null) {
27+
if (package.Name != null && !_packagesByName.ContainsKey(package.Name)) {
2828
_packagesSorted.Add(package);
2929
_packagesByName[package.Name] = package;
3030
}

Nodejs/Product/Npm/SPI/NodeModules.cs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,14 @@ public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages,
7575
}
7676

7777
if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson) {
78-
// Iterate through all dependencies in package.json
79-
foreach (var dependency in parent.PackageJson.AllDependencies) {
78+
// Iterate through all dependencies in the root package.json
79+
// Otherwise, only iterate through "dependencies" because iterating through optional, bundle, etc. dependencies
80+
// becomes unmanageable when they are already installed at the root of the project, and the performance impact
81+
// typically isn't worth the value add.
82+
var dependencies = depth == 0 ? parent.PackageJson.AllDependencies : parent.PackageJson.Dependencies;
83+
foreach (var dependency in dependencies) {
8084
var moduleDir = modulesBase;
81-
85+
8286
// try to find folder by recursing up tree
8387
do {
8488
moduleDir = Path.Combine(moduleDir, dependency.Name);
@@ -127,16 +131,25 @@ private bool AddModuleIfNotExists(IRootPackage parent, string moduleDir, bool sh
127131
return false;
128132
}
129133

130-
if (moduleInfo.RequiredBy.Contains(parent.Name)) {
131-
return true;
134+
IPackage package = moduleInfo.Package;
135+
136+
if (package == null || depth == 1 || !moduleInfo.RequiredBy.Contains(parent.Path)) {
137+
// Create a dummy value for the current package to prevent infinite loops
138+
moduleInfo.Package = new PackageProxy();
139+
140+
moduleInfo.RequiredBy.Add(parent.Path);
141+
142+
var pkg = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, _allModules, depth);
143+
if (dependency != null) {
144+
pkg.RequestedVersionRange = dependency.VersionRangeText;
145+
}
146+
147+
package = moduleInfo.Package = pkg;
132148
}
133149

134-
moduleInfo.RequiredBy.Add(parent.Name);
135-
var package = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, _allModules, depth);
136-
if (dependency != null) {
137-
package.RequestedVersionRange = dependency.VersionRangeText;
150+
if (parent as IPackage == null || !package.IsMissing || showMissingDevOptionalSubPackages) {
151+
AddModule(package);
138152
}
139-
AddModule(package);
140153

141154
return true;
142155
}
@@ -158,6 +171,9 @@ public override int GetDepth(string filepath) {
158171

159172
internal class ModuleInfo {
160173
public int Depth { get; set; }
174+
175+
public IPackage Package { get; set; }
176+
161177
public IList<string> RequiredBy { get; set; }
162178

163179
internal ModuleInfo(int depth) {

0 commit comments

Comments
 (0)