@@ -191,6 +191,16 @@ export interface DepOptimizationMetadata {
191
191
* This is checked on server startup to avoid unnecessary re-bundles.
192
192
*/
193
193
hash : string
194
+ /**
195
+ * This hash is determined by dependency lockfiles.
196
+ * This is checked on server startup to avoid unnecessary re-bundles.
197
+ */
198
+ lockfileHash : string
199
+ /**
200
+ * This hash is determined by user config.
201
+ * This is checked on server startup to avoid unnecessary re-bundles.
202
+ */
203
+ configHash : string
194
204
/**
195
205
* The browser hash is determined by the main hash plus additional dependencies
196
206
* discovered at runtime. This is used to invalidate browser requests to
@@ -310,9 +320,11 @@ export function initDepsOptimizerMetadata(
310
320
ssr : boolean ,
311
321
timestamp ?: string ,
312
322
) : DepOptimizationMetadata {
313
- const hash = getDepHash ( config , ssr )
323
+ const { lockfileHash , configHash , hash } = getDepHash ( config , ssr )
314
324
return {
315
325
hash,
326
+ lockfileHash,
327
+ configHash,
316
328
browserHash : getOptimizedBrowserHash ( hash , { } , timestamp ) ,
317
329
optimized : { } ,
318
330
chunks : { } ,
@@ -363,11 +375,21 @@ export async function loadCachedDepOptimizationMetadata(
363
375
)
364
376
} catch ( e ) { }
365
377
// hash is consistent, no need to re-bundle
366
- if ( cachedMetadata && cachedMetadata . hash === getDepHash ( config , ssr ) ) {
367
- log ?.( 'Hash is consistent. Skipping. Use --force to override.' )
368
- // Nothing to commit or cancel as we are using the cache, we only
369
- // need to resolve the processing promise so requests can move on
370
- return cachedMetadata
378
+ if ( cachedMetadata ) {
379
+ if ( cachedMetadata . lockfileHash !== getLockfileHash ( config , ssr ) ) {
380
+ config . logger . info (
381
+ 'Re-optimizing dependencies because lockfile has changed' ,
382
+ )
383
+ } else if ( cachedMetadata . configHash !== getConfigHash ( config , ssr ) ) {
384
+ config . logger . info (
385
+ 'Re-optimizing dependencies because vite config has changed' ,
386
+ )
387
+ } else {
388
+ log ?.( 'Hash is consistent. Skipping. Use --force to override.' )
389
+ // Nothing to commit or cancel as we are using the cache, we only
390
+ // need to resolve the processing promise so requests can move on
391
+ return cachedMetadata
392
+ }
371
393
}
372
394
} else {
373
395
config . logger . info ( 'Forced re-optimization of dependencies' )
@@ -417,7 +439,7 @@ export function toDiscoveredDependencies(
417
439
timestamp ?: string ,
418
440
) : Record < string , OptimizedDepInfo > {
419
441
const browserHash = getOptimizedBrowserHash (
420
- getDepHash ( config , ssr ) ,
442
+ getDepHash ( config , ssr ) . hash ,
421
443
deps ,
422
444
timestamp ,
423
445
)
@@ -975,17 +997,15 @@ function parseDepsOptimizerMetadata(
975
997
jsonMetadata : string ,
976
998
depsCacheDir : string ,
977
999
) : DepOptimizationMetadata | undefined {
978
- const { hash, browserHash, optimized, chunks } = JSON . parse (
979
- jsonMetadata ,
980
- ( key : string , value : string ) => {
1000
+ const { hash, lockfileHash, configHash, browserHash, optimized, chunks } =
1001
+ JSON . parse ( jsonMetadata , ( key : string , value : string ) => {
981
1002
// Paths can be absolute or relative to the deps cache dir where
982
1003
// the _metadata.json is located
983
1004
if ( key === 'file' || key === 'src' ) {
984
1005
return normalizePath ( path . resolve ( depsCacheDir , value ) )
985
1006
}
986
1007
return value
987
- } ,
988
- )
1008
+ } )
989
1009
if (
990
1010
! chunks ||
991
1011
Object . values ( optimized ) . some ( ( depInfo : any ) => ! depInfo . fileHash )
@@ -995,6 +1015,8 @@ function parseDepsOptimizerMetadata(
995
1015
}
996
1016
const metadata = {
997
1017
hash,
1018
+ lockfileHash,
1019
+ configHash,
998
1020
browserHash,
999
1021
optimized : { } ,
1000
1022
discovered : { } ,
@@ -1029,10 +1051,13 @@ function stringifyDepsOptimizerMetadata(
1029
1051
metadata : DepOptimizationMetadata ,
1030
1052
depsCacheDir : string ,
1031
1053
) {
1032
- const { hash, browserHash, optimized, chunks } = metadata
1054
+ const { hash, configHash, lockfileHash, browserHash, optimized, chunks } =
1055
+ metadata
1033
1056
return JSON . stringify (
1034
1057
{
1035
1058
hash,
1059
+ configHash,
1060
+ lockfileHash,
1036
1061
browserHash,
1037
1062
optimized : Object . fromEntries (
1038
1063
Object . values ( optimized ) . map (
@@ -1187,27 +1212,11 @@ const lockfileFormats = [
1187
1212
} )
1188
1213
const lockfileNames = lockfileFormats . map ( ( l ) => l . name )
1189
1214
1190
- export function getDepHash ( config : ResolvedConfig , ssr : boolean ) : string {
1191
- const lockfilePath = lookupFile ( config . root , lockfileNames )
1192
- let content = lockfilePath ? fs . readFileSync ( lockfilePath , 'utf-8' ) : ''
1193
- if ( lockfilePath ) {
1194
- const lockfileName = path . basename ( lockfilePath )
1195
- const { checkPatches } = lockfileFormats . find (
1196
- ( f ) => f . name === lockfileName ,
1197
- ) !
1198
- if ( checkPatches ) {
1199
- // Default of https://github.com/ds300/patch-package
1200
- const fullPath = path . join ( path . dirname ( lockfilePath ) , 'patches' )
1201
- const stat = tryStatSync ( fullPath )
1202
- if ( stat ?. isDirectory ( ) ) {
1203
- content += stat . mtimeMs . toString ( )
1204
- }
1205
- }
1206
- }
1207
- // also take config into account
1215
+ function getConfigHash ( config : ResolvedConfig , ssr : boolean ) : string {
1216
+ // Take config into account
1208
1217
// only a subset of config options that can affect dep optimization
1209
1218
const optimizeDeps = getDepOptimizationConfig ( config , ssr )
1210
- content + = JSON . stringify (
1219
+ const content = JSON . stringify (
1211
1220
{
1212
1221
mode : process . env . NODE_ENV || config . mode ,
1213
1222
root : config . root ,
@@ -1238,6 +1247,40 @@ export function getDepHash(config: ResolvedConfig, ssr: boolean): string {
1238
1247
return getHash ( content )
1239
1248
}
1240
1249
1250
+ function getLockfileHash ( config : ResolvedConfig , ssr : boolean ) : string {
1251
+ const lockfilePath = lookupFile ( config . root , lockfileNames )
1252
+ let content = lockfilePath ? fs . readFileSync ( lockfilePath , 'utf-8' ) : ''
1253
+ if ( lockfilePath ) {
1254
+ const lockfileName = path . basename ( lockfilePath )
1255
+ const { checkPatches } = lockfileFormats . find (
1256
+ ( f ) => f . name === lockfileName ,
1257
+ ) !
1258
+ if ( checkPatches ) {
1259
+ // Default of https://github.com/ds300/patch-package
1260
+ const fullPath = path . join ( path . dirname ( lockfilePath ) , 'patches' )
1261
+ const stat = tryStatSync ( fullPath )
1262
+ if ( stat ?. isDirectory ( ) ) {
1263
+ content += stat . mtimeMs . toString ( )
1264
+ }
1265
+ }
1266
+ }
1267
+ return getHash ( content )
1268
+ }
1269
+
1270
+ function getDepHash (
1271
+ config : ResolvedConfig ,
1272
+ ssr : boolean ,
1273
+ ) : { lockfileHash : string ; configHash : string ; hash : string } {
1274
+ const lockfileHash = getLockfileHash ( config , ssr )
1275
+ const configHash = getConfigHash ( config , ssr )
1276
+ const hash = getHash ( lockfileHash + configHash )
1277
+ return {
1278
+ hash,
1279
+ lockfileHash,
1280
+ configHash,
1281
+ }
1282
+ }
1283
+
1241
1284
function getOptimizedBrowserHash (
1242
1285
hash : string ,
1243
1286
deps : Record < string , string > ,
0 commit comments