Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include invalidation hash in asset content keys #7526

Merged
merged 2 commits into from Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 15 additions & 6 deletions packages/core/core/src/Transformation.js
Expand Up @@ -283,15 +283,21 @@ export default class Transformation {

if (!initialCacheEntry) {
let pipelineHash = await this.getPipelineHash(pipeline);
let invalidationCacheKey = await getInvalidationHash(
assets.flatMap(asset => asset.getInvalidations()),
this.options,
);
let resultCacheKey = this.getCacheKey(
[initialAsset],
await getInvalidationHash(
assets.flatMap(asset => asset.getInvalidations()),
this.options,
),
invalidationCacheKey,
pipelineHash,
);
await this.writeToCache(
resultCacheKey,
assets,
invalidationCacheKey,
pipelineHash,
);
await this.writeToCache(resultCacheKey, assets, pipelineHash);
} else {
// See above TODO, this should be per-pipeline
for (let i of this.request.invalidations) {
Expand Down Expand Up @@ -541,9 +547,12 @@ export default class Transformation {
async writeToCache(
cacheKey: string,
assets: Array<UncommittedAsset>,
invalidationHash: string,
pipelineHash: string,
): Promise<void> {
await Promise.all(assets.map(asset => asset.commit(pipelineHash)));
await Promise.all(
assets.map(asset => asset.commit(invalidationHash + pipelineHash)),
);

this.options.cache.set(cacheKey, {
$$raw: true,
Expand Down
47 changes: 47 additions & 0 deletions packages/core/integration-tests/test/cache.js
Expand Up @@ -5789,6 +5789,53 @@ describe('cache', function () {
}
});

it('properly handles included files even after when changing back to a cached state', async function () {
this.timeout(15000);
let subscription;
let fixture = path.join(__dirname, '/integration/included-file');
try {
let b = bundler(path.join(fixture, 'index.txt'), {
inputFS: overlayFS,
shouldDisableCache: false,
});
await overlayFS.mkdirp(fixture);
await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'a');
subscription = await b.watch();
let event = await getNextBuild(b);
invariant(event.type === 'buildSuccess');
let output1 = await overlayFS.readFile(
event.bundleGraph.getBundles()[0].filePath,
'utf8',
);
assert.strictEqual(output1, 'a');

// Change included file
await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'b');
event = await getNextBuild(b);
invariant(event.type === 'buildSuccess');
let output2 = await overlayFS.readFile(
event.bundleGraph.getBundles()[0].filePath,
'utf8',
);
assert.strictEqual(output2, 'b');

// Change included file back
await overlayFS.writeFile(path.join(fixture, 'included.txt'), 'a');
event = await getNextBuild(b);
invariant(event.type === 'buildSuccess');
let output3 = await overlayFS.readFile(
event.bundleGraph.getBundles()[0].filePath,
'utf8',
);
assert.strictEqual(output3, 'a');
} finally {
if (subscription) {
await subscription.unsubscribe();
subscription = null;
}
}
});

it('should support moving the project root', async function () {
// This test relies on the real filesystem because the memory fs doesn't support renames.
// But renameSync is broken on windows in CI with EPERM errors. Just skip this test for now.
Expand Down