@@ -191,6 +191,16 @@ export interface DepOptimizationMetadata {
191191 * This is checked on server startup to avoid unnecessary re-bundles.
192192 */
193193 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
194204 /**
195205 * The browser hash is determined by the main hash plus additional dependencies
196206 * discovered at runtime. This is used to invalidate browser requests to
@@ -310,9 +320,11 @@ export function initDepsOptimizerMetadata(
310320 ssr : boolean ,
311321 timestamp ?: string ,
312322) : DepOptimizationMetadata {
313- const hash = getDepHash ( config , ssr )
323+ const { lockfileHash , configHash , hash } = getDepHash ( config , ssr )
314324 return {
315325 hash,
326+ lockfileHash,
327+ configHash,
316328 browserHash : getOptimizedBrowserHash ( hash , { } , timestamp ) ,
317329 optimized : { } ,
318330 chunks : { } ,
@@ -363,11 +375,21 @@ export async function loadCachedDepOptimizationMetadata(
363375 )
364376 } catch ( e ) { }
365377 // 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+ }
371393 }
372394 } else {
373395 config . logger . info ( 'Forced re-optimization of dependencies' )
@@ -417,7 +439,7 @@ export function toDiscoveredDependencies(
417439 timestamp ?: string ,
418440) : Record < string , OptimizedDepInfo > {
419441 const browserHash = getOptimizedBrowserHash (
420- getDepHash ( config , ssr ) ,
442+ getDepHash ( config , ssr ) . hash ,
421443 deps ,
422444 timestamp ,
423445 )
@@ -975,17 +997,15 @@ function parseDepsOptimizerMetadata(
975997 jsonMetadata : string ,
976998 depsCacheDir : string ,
977999) : 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 ) => {
9811002 // Paths can be absolute or relative to the deps cache dir where
9821003 // the _metadata.json is located
9831004 if ( key === 'file' || key === 'src' ) {
9841005 return normalizePath ( path . resolve ( depsCacheDir , value ) )
9851006 }
9861007 return value
987- } ,
988- )
1008+ } )
9891009 if (
9901010 ! chunks ||
9911011 Object . values ( optimized ) . some ( ( depInfo : any ) => ! depInfo . fileHash )
@@ -995,6 +1015,8 @@ function parseDepsOptimizerMetadata(
9951015 }
9961016 const metadata = {
9971017 hash,
1018+ lockfileHash,
1019+ configHash,
9981020 browserHash,
9991021 optimized : { } ,
10001022 discovered : { } ,
@@ -1029,10 +1051,13 @@ function stringifyDepsOptimizerMetadata(
10291051 metadata : DepOptimizationMetadata ,
10301052 depsCacheDir : string ,
10311053) {
1032- const { hash, browserHash, optimized, chunks } = metadata
1054+ const { hash, configHash, lockfileHash, browserHash, optimized, chunks } =
1055+ metadata
10331056 return JSON . stringify (
10341057 {
10351058 hash,
1059+ configHash,
1060+ lockfileHash,
10361061 browserHash,
10371062 optimized : Object . fromEntries (
10381063 Object . values ( optimized ) . map (
@@ -1187,27 +1212,11 @@ const lockfileFormats = [
11871212} )
11881213const lockfileNames = lockfileFormats . map ( ( l ) => l . name )
11891214
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
12081217 // only a subset of config options that can affect dep optimization
12091218 const optimizeDeps = getDepOptimizationConfig ( config , ssr )
1210- content + = JSON . stringify (
1219+ const content = JSON . stringify (
12111220 {
12121221 mode : process . env . NODE_ENV || config . mode ,
12131222 root : config . root ,
@@ -1238,6 +1247,40 @@ export function getDepHash(config: ResolvedConfig, ssr: boolean): string {
12381247 return getHash ( content )
12391248}
12401249
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+
12411284function getOptimizedBrowserHash (
12421285 hash : string ,
12431286 deps : Record < string , string > ,
0 commit comments