@@ -9,14 +9,26 @@ const d = debug('electron-forge:rebuild');
9
9
10
10
export default async ( buildPath , electronVersion , pPlatform , pArch ) => {
11
11
const rebuilds = [ ] ;
12
+ let rebuildCount = 0 ;
13
+ let rebuildCompleteCount = 0 ;
14
+ const prodDeps = { } ;
15
+
16
+ const nativeSpinner = ora . ora ( `Preparing native dependencies ${ rebuildCompleteCount } /${ rebuildCount } ` ) . start ( ) ;
17
+ const updateNativeSpinner = ( ) => {
18
+ nativeSpinner . text = `Preparing native dependencies ${ rebuildCompleteCount } /${ rebuildCount } ` ;
19
+ } ;
12
20
13
21
const rebuildModuleAt = async ( modulePath ) => {
14
22
if ( await fs . exists ( path . resolve ( modulePath , 'binding.gyp' ) ) ) {
15
23
const metaPath = path . resolve ( modulePath , 'build' , 'Release' , '.forge-meta' ) ;
24
+ rebuildCount += 1 ;
25
+ updateNativeSpinner ( ) ;
16
26
if ( await fs . exists ( metaPath ) ) {
17
27
const meta = await fs . readFile ( metaPath , 'utf8' ) ;
18
28
if ( meta === pArch ) {
19
29
d ( `skipping: ${ path . basename ( modulePath ) } as it is already built` ) ;
30
+ rebuildCompleteCount += 1 ;
31
+ updateNativeSpinner ( ) ;
20
32
return ;
21
33
}
22
34
}
@@ -59,11 +71,14 @@ export default async (buildPath, electronVersion, pPlatform, pArch) => {
59
71
if ( code !== 0 ) return reject ( new Error ( `Failed to rebuild: ${ modulePath } \n\n${ output } ` ) ) ;
60
72
await fs . mkdirs ( path . dirname ( metaPath ) ) ;
61
73
await fs . writeFile ( metaPath , pArch ) ;
74
+ rebuildCompleteCount += 1 ;
75
+ updateNativeSpinner ( ) ;
62
76
resolve ( ) ;
63
77
} ) ;
64
78
} ) ;
65
79
}
66
80
} ;
81
+
67
82
const rebuildAllModulesIn = ( nodeModulesPath ) => {
68
83
for ( const modulePath of fs . readdirSync ( nodeModulesPath ) ) {
69
84
rebuilds . push ( rebuildModuleAt ( path . resolve ( nodeModulesPath , modulePath ) ) ) ;
@@ -75,7 +90,40 @@ export default async (buildPath, electronVersion, pPlatform, pArch) => {
75
90
}
76
91
}
77
92
} ;
78
- const nativeSpinner = ora . ora ( 'Preparing native dependencies' ) . start ( ) ;
93
+
94
+ const findModule = async ( moduleName , fromDir , foundFn ) => {
95
+ let targetDir = fromDir ;
96
+ const foundFns = [ ] ;
97
+ while ( targetDir !== buildPath ) {
98
+ const testPath = path . resolve ( targetDir , 'node_modules' , moduleName ) ;
99
+ if ( await fs . exists ( testPath ) ) {
100
+ foundFns . push ( foundFn ( testPath ) ) ;
101
+ }
102
+ targetDir = path . dirname ( targetDir ) ;
103
+ }
104
+ await Promise . all ( foundFns ) ;
105
+ } ;
106
+
107
+ const markChildrenAsProdDeps = async ( modulePath ) => {
108
+ const childPackageJSON = JSON . parse ( await fs . readFile ( path . resolve ( modulePath , 'package.json' ) , 'utf8' ) ) ;
109
+ const moduleWait = [ ] ;
110
+ Object . keys ( childPackageJSON . dependencies || { } ) . forEach ( ( key ) => {
111
+ if ( prodDeps [ key ] ) return ;
112
+ prodDeps [ key ] = true ;
113
+ moduleWait . push ( findModule ( key , modulePath , markChildrenAsProdDeps ) ) ;
114
+ } ) ;
115
+ await Promise . all ( moduleWait ) ;
116
+ } ;
117
+
118
+ const rootPackageJSON = JSON . parse ( await fs . readFile ( path . resolve ( buildPath , 'package.json' ) , 'utf8' ) ) ;
119
+ const markWaiters = [ ] ;
120
+ Object . keys ( rootPackageJSON . dependencies || { } ) . concat ( Object . keys ( rootPackageJSON . optionalDependencies || { } ) ) . forEach ( ( key ) => {
121
+ prodDeps [ key ] = true ;
122
+ markWaiters . push ( markChildrenAsProdDeps ( path . resolve ( buildPath , 'node_modules' , key ) ) ) ;
123
+ } ) ;
124
+
125
+ await Promise . all ( markWaiters ) ;
126
+
79
127
rebuildAllModulesIn ( path . resolve ( buildPath , 'node_modules' ) ) ;
80
128
try {
81
129
await Promise . all ( rebuilds ) ;
0 commit comments