Skip to content

Commit b8e8973

Browse files
authored
Invalidate cache when dependencies included in parent change (#514)
Some dependencies are pre-compiled into their parent assets, e.g. stylus imports. But we still need to invalidate the cache if any of those files change. Now the FSCache looks for deps with `includedInParent: true`, and stores an mtime in the cache file. When reading from the cache, those deps are checked to see if they changed and if so, the parent asset is invalidated.
1 parent 9143f4b commit b8e8973

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/FSCache.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ const path = require('path');
33
const md5 = require('./utils/md5');
44
const objectHash = require('./utils/objectHash');
55
const pkg = require('../package.json');
6-
const json5 = require('json5');
76

87
// These keys can affect the output, so if they differ, the cache should not match
98
const OPTION_KEYS = ['publicURL', 'minify', 'hmr'];
@@ -30,16 +29,42 @@ class FSCache {
3029
return path.join(this.dir, hash + '.json');
3130
}
3231

32+
async writeDepMtimes(data) {
33+
// Write mtimes for each dependent file that is already compiled into this asset
34+
for (let dep of data.dependencies) {
35+
if (dep.includedInParent) {
36+
let stats = await fs.stat(dep.name);
37+
dep.mtime = stats.mtime.getTime();
38+
}
39+
}
40+
}
41+
3342
async write(filename, data) {
3443
try {
3544
await this.ensureDirExists();
45+
await this.writeDepMtimes(data);
3646
await fs.writeFile(this.getCacheFile(filename), JSON.stringify(data));
3747
this.invalidated.delete(filename);
3848
} catch (err) {
3949
console.error('Error writing to cache', err);
4050
}
4151
}
4252

53+
async checkDepMtimes(data) {
54+
// Check mtimes for files that are already compiled into this asset
55+
// If any of them changed, invalidate.
56+
for (let dep of data.dependencies) {
57+
if (dep.includedInParent) {
58+
let stats = await fs.stat(dep.name);
59+
if (stats.mtime > dep.mtime) {
60+
return false;
61+
}
62+
}
63+
}
64+
65+
return true;
66+
}
67+
4368
async read(filename) {
4469
if (this.invalidated.has(filename)) {
4570
return null;
@@ -55,8 +80,13 @@ class FSCache {
5580
return null;
5681
}
5782

58-
let data = await fs.readFile(cacheFile);
59-
return json5.parse(data);
83+
let json = await fs.readFile(cacheFile);
84+
let data = JSON.parse(json);
85+
if (!await this.checkDepMtimes(data)) {
86+
return null;
87+
}
88+
89+
return data;
6090
} catch (err) {
6191
return null;
6292
}

0 commit comments

Comments
 (0)