@@ -16,6 +16,9 @@ interface PackageJson {
16
16
peerDependencies : {
17
17
[ key : string ] : string ;
18
18
} ;
19
+ optionalDependencies : {
20
+ [ key : string ] : string ;
21
+ } ;
19
22
20
23
// What is a peerDevDependency? This is not a standard.
21
24
// This is an array of package names found in `peerDependencies` which should be installed as devDependencies.
@@ -43,6 +46,7 @@ interface PackageDependencies {
43
46
dependencies : Dependency [ ] ;
44
47
devDependencies : Dependency [ ] ;
45
48
peerDependencies : Dependency [ ] ;
49
+ optionalDependencies : Dependency [ ] ;
46
50
peerDevDependencies : string [ ] ;
47
51
}
48
52
@@ -90,15 +94,24 @@ export function walkPackageDependencyTree(packagePath: string, visitor: Dependen
90
94
}
91
95
92
96
const dependencyPath = resolvePackageDir ( packagePath , dependency . name ) ;
93
- if ( dependencyPath ) {
94
- walkPackageDependencyTree ( dependencyPath , visitor , visitedPaths , options ) ;
95
- } else {
96
- console . log ( `WARN: Unable to resolve package ${ dependency . name } from ${ packagePath } ` )
97
+
98
+ if ( ! dependencyPath ) {
99
+ if ( packageDependencies . optionalDependencies . some ( x => x . name === dependency . name ) ) {
100
+ // don't fail if the missing dependency is in optionalDependencies
101
+ if ( options . debug ) {
102
+ console . log ( `Ignoring missing optional dependency ${ dependency . name } from ${ packagePath } ` ) ;
103
+ }
104
+ return ;
105
+ } else {
106
+ throw new Error ( `WARN: Unable to resolve package ${ dependency . name } from ${ packagePath } ` )
107
+ }
97
108
}
109
+
110
+ walkPackageDependencyTree ( dependencyPath , visitor , visitedPaths , options ) ;
98
111
}
99
-
100
- if ( isRootPackage ) packageDependencies . devDependencies . forEach ( walkDependency ) ;
101
- if ( ( isRootPackage ) || ( ! options . runOnlyOnRootDependencies ) ) packageDependencies . dependencies . forEach ( walkDependency )
112
+
113
+ if ( isRootPackage ) packageDependencies . devDependencies . forEach ( walkDependency ) ;
114
+ if ( isRootPackage || ! options . runOnlyOnRootDependencies ) packageDependencies . dependencies . forEach ( walkDependency )
102
115
}
103
116
104
117
function buildDependencyArray ( packagePath : string , packageJson : PackageJson , dependenciesObject : any ) : Dependency [ ] {
@@ -112,15 +125,23 @@ function buildDependencyArray(packagePath: string, packageJson: PackageJson, dep
112
125
}
113
126
114
127
export function getPackageDependencies ( packagePath : string , packageJson : PackageJson ) : PackageDependencies {
115
- const { name, dependencies = { } , devDependencies = { } , peerDependencies = { } , peerDevDependencies = [ ] } = packageJson ;
116
-
117
- const applyPeerDevDependencies = ( dep : Dependency ) : Dependency =>
128
+ const {
129
+ name,
130
+ dependencies = { } ,
131
+ devDependencies = { } ,
132
+ optionalDependencies = { } ,
133
+ peerDependencies = { } ,
134
+ peerDevDependencies = [ ]
135
+ } = packageJson ;
136
+
137
+ const applyPeerDevDependencies = ( dep : Dependency ) : Dependency =>
118
138
( { ...dep , isPeerDevDependency : peerDevDependencies . includes && peerDevDependencies . includes ( dep . name ) } ) ;
119
139
120
140
return {
121
141
packageName : name ,
122
142
dependencies : buildDependencyArray ( packagePath , packageJson , dependencies ) ,
123
143
devDependencies : buildDependencyArray ( packagePath , packageJson , devDependencies ) ,
144
+ optionalDependencies : buildDependencyArray ( packagePath , packageJson , optionalDependencies ) ,
124
145
peerDependencies : buildDependencyArray ( packagePath , packageJson , peerDependencies ) . map ( applyPeerDevDependencies ) ,
125
146
peerDevDependencies,
126
147
} ;
0 commit comments