@@ -41,9 +41,11 @@ function getPlatformInfo(): IPlatformInfo {
4141}
4242
4343const END_TOKEN : string = '/package.json":' ;
44+ const SUBPACKAGE_CACHE_FILE_VERSION : 1 = 1 ;
4445
4546interface INestedPackageJsonCache {
4647 subPackagesByIntegrity : [ string , string [ ] | boolean ] [ ] ;
48+ version : number ;
4749}
4850
4951/**
@@ -93,8 +95,14 @@ export async function afterInstallAsync(
9395 try {
9496 const cacheContent : string = await FileSystem . readFileAsync ( subPackageCacheFilePath ) ;
9597 const cacheJson : INestedPackageJsonCache = JSON . parse ( cacheContent ) ;
96- oldSubPackagesByIntegrity = new Map ( cacheJson . subPackagesByIntegrity ) ;
97- terminal . writeLine ( `Loaded subpackage cache from ${ subPackageCacheFilePath } ` ) ;
98+ if ( cacheJson . version !== SUBPACKAGE_CACHE_FILE_VERSION ) {
99+ terminal . writeLine (
100+ `Expected subpackage cache version ${ SUBPACKAGE_CACHE_FILE_VERSION } , got ${ cacheJson . version } `
101+ ) ;
102+ } else {
103+ oldSubPackagesByIntegrity = new Map ( cacheJson . subPackagesByIntegrity ) ;
104+ terminal . writeLine ( `Loaded subpackage cache from ${ subPackageCacheFilePath } ` ) ;
105+ }
98106 } catch ( err ) {
99107 // Ignore
100108 }
@@ -196,8 +204,9 @@ export async function afterInstallAsync(
196204 terminal . writeDebugLine (
197205 `Nested "package.json" files found for package at ${ descriptionFileRoot } : ${ result . join ( ', ' ) } `
198206 ) ;
207+ // Clone this array to ensure that mutations don't affect the subpackage cache.
199208 // eslint-disable-next-line require-atomic-updates
200- context . nestedPackageDirs = result ;
209+ context . nestedPackageDirs = [ ... result ] ;
201210 }
202211 }
203212
@@ -209,6 +218,21 @@ export async function afterInstallAsync(
209218 } ) ;
210219 }
211220
221+ // Serialize this before `computeResolverCacheFromLockfileAsync` because bundledDependencies get removed
222+ // from the `nestedPackageDirs` array. We clone above for safety, but this is making doubly sure.
223+ const newSubPackageCache : INestedPackageJsonCache = {
224+ version : SUBPACKAGE_CACHE_FILE_VERSION ,
225+ subPackagesByIntegrity : Array . from ( subPackagesByIntegrity )
226+ } ;
227+ const serializedSubpackageCache : string = JSON . stringify ( newSubPackageCache ) ;
228+ const writeSubPackageCachePromise : Promise < void > = FileSystem . writeFileAsync (
229+ subPackageCacheFilePath ,
230+ serializedSubpackageCache ,
231+ {
232+ ensureFolderExists : true
233+ }
234+ ) ;
235+
212236 const cacheFile : IResolverCacheFile = await computeResolverCacheFromLockfileAsync ( {
213237 workspaceRoot,
214238 commonPrefixToTrim : rushRoot ,
@@ -218,19 +242,13 @@ export async function afterInstallAsync(
218242 afterExternalPackagesAsync
219243 } ) ;
220244
221- const newSubPackageCache : string = JSON . stringify ( {
222- subPackagesByIntegrity : Array . from ( subPackagesByIntegrity )
223- } ) ;
224-
225245 const serialized : string = JSON . stringify ( cacheFile ) ;
226246
227247 await Promise . all ( [
228248 FileSystem . writeFileAsync ( cacheFilePath , serialized , {
229249 ensureFolderExists : true
230250 } ) ,
231- FileSystem . writeFileAsync ( subPackageCacheFilePath , newSubPackageCache , {
232- ensureFolderExists : true
233- } )
251+ writeSubPackageCachePromise
234252 ] ) ;
235253
236254 terminal . writeLine ( `Resolver cache written.` ) ;
0 commit comments