diff --git a/packages/metro/src/DeltaBundler/DeltaCalculator.js b/packages/metro/src/DeltaBundler/DeltaCalculator.js index 3af7dbae08..637f0e7728 100644 --- a/packages/metro/src/DeltaBundler/DeltaCalculator.js +++ b/packages/metro/src/DeltaBundler/DeltaCalculator.js @@ -304,11 +304,12 @@ export default class DeltaCalculator extends EventEmitter { } }); - // An added file that already has a module in the graph was deleted and - // recreated while a build was in flight. The graph never saw the deletion, - // so the module it holds is stale and needs revisiting. + // An added file the graph already holds was deleted and recreated during + // a build, so its module is stale. It is modified, not added, since it + // never left the graph. addedFiles.forEach((filePath: string) => { if (this._graph.dependencies.has(filePath)) { + addedFiles.delete(filePath); modifiedFiles.add(filePath); } }); diff --git a/packages/metro/src/DeltaBundler/__tests__/DeltaCalculator-test.js b/packages/metro/src/DeltaBundler/__tests__/DeltaCalculator-test.js index f5750b1e53..a180e8c672 100644 --- a/packages/metro/src/DeltaBundler/__tests__/DeltaCalculator-test.js +++ b/packages/metro/src/DeltaBundler/__tests__/DeltaCalculator-test.js @@ -629,6 +629,28 @@ describe.each(['posix', 'win32'])('DeltaCalculator (%s)', osPlatform => { expect(traverseDependencies.mock.calls[1][0]).toEqual([p('/bundle')]); }); + test('should not traverse a re-added file deleted after a failed delta', async () => { + await deltaCalculator.getDelta({reset: false, shallow: false}); + + // As after a delete and re-add during an earlier build. + emitChange({addedFiles: ['foo']}); + traverseDependencies.mockRejectedValueOnce(new Error('Syntax error')); + await expect( + deltaCalculator.getDelta({reset: false, shallow: false}), + ).rejects.toBeInstanceOf(Error); + + emitChange({removedFiles: ['foo']}); + traverseDependencies.mockResolvedValueOnce({ + added: new Map(), + modified: new Map([[p('/bundle'), entryModule]]), + deleted: new Set([p('/foo')]), + }); + await deltaCalculator.getDelta({reset: false, shallow: false}); + + expect(traverseDependencies).toHaveBeenCalledTimes(2); + expect(traverseDependencies.mock.calls[1][0]).toEqual([p('/bundle')]); + }); + test('should traverse a file re-added while a successful delta was being built', async () => { await deltaCalculator.getDelta({reset: false, shallow: false});