From 56133115cd70061d170c6d9f7bb7ec9166da76ab Mon Sep 17 00:00:00 2001 From: Moti Zilberman Date: Mon, 1 Apr 2019 17:36:46 +0100 Subject: [PATCH] fix: sort modules in debugger delta patcher to match source map order (#279) Summary: --------- Context: https://github.com/facebook/metro/issues/380, https://github.com/facebook/react-native/issues/23955 Fixes a discrepancy between the order of modules in the source map and in the actual bundle, caused by a change in Metro (see details in https://github.com/facebook/metro/issues/380#issuecomment-478633831). Consequently fixes React Native remote JS debugging. Test Plan: ---------- 1. Made the same change in my checkout of the repro code from https://github.com/facebook/metro/issues/380 and verified debugging works. 2. Added unit tests. --- .../server/debugger-ui/DeltaPatcher.js | 5 +- .../__tests__/DeltaPatcher-test.js | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/server/debugger-ui/DeltaPatcher.js b/packages/cli/src/commands/server/debugger-ui/DeltaPatcher.js index ed950295f6..25c9f36900 100644 --- a/packages/cli/src/commands/server/debugger-ui/DeltaPatcher.js +++ b/packages/cli/src/commands/server/debugger-ui/DeltaPatcher.js @@ -119,7 +119,10 @@ getAllModules() { return [].concat( [this._lastBundle.pre], - Array.from(this._lastBundle.modules.values()), + // Sort modules so they match the source map emitted by Metro >= 0.51.0 + Array.from(this._lastBundle.modules.entries()) + .sort(([id1], [id2]) => id1 - id2) + .map(([id, contents]) => contents), [this._lastBundle.post], ); } diff --git a/packages/cli/src/commands/server/debugger-ui/__tests__/DeltaPatcher-test.js b/packages/cli/src/commands/server/debugger-ui/__tests__/DeltaPatcher-test.js index 2bd9db3396..caae8e599c 100644 --- a/packages/cli/src/commands/server/debugger-ui/__tests__/DeltaPatcher-test.js +++ b/packages/cli/src/commands/server/debugger-ui/__tests__/DeltaPatcher-test.js @@ -108,4 +108,55 @@ describe('DeltaPatcher', () => { expect(dp.getLastNumModifiedFiles()).toBe(2); expect(dp.getAllModules()).toEqual(['pre2', '__d(4);', '__d(5);', 'post2']); }); + + it('should sort modules after receiving an unsorted base bundle', () => { + const dp = new window.DeltaPatcher(); + global.Date = jest.fn(); + dp.applyDelta({ + base: true, + revisionId: 'rev0', + pre: 'pre0', + post: 'post0', + modules: [[2, '__d(2);'], [3, '__d(3);'], [0, '__d(0);'], [1, '__d(1);']], + }); + expect(dp.getLastRevisionId()).toBe('rev0'); + expect(dp.getLastModifiedDate()).toBe(global.Date.mock.instances[0]); + expect(dp.getLastNumModifiedFiles()).toBe(4); + expect(dp.getAllModules()).toEqual([ + 'pre0', + '__d(0);', + '__d(1);', + '__d(2);', + '__d(3);', + 'post0', + ]); + }); + + it('should sort modules after receiving an unsorted delta bundle', () => { + const dp = new window.DeltaPatcher(); + dp.applyDelta({ + base: true, + revisionId: 'rev0', + pre: 'pre0', + post: 'post0', + modules: [[2, '__d(2);'], [1, '__d(1);'], [0, '__d(0);']], + }); + global.Date = jest.fn(); + dp.applyDelta({ + base: false, + revisionId: 'rev1', + modules: [[3, '__d(3);'], [1, '__d(1.1);']], + deleted: [0], + }); + expect(dp.getLastRevisionId()).toBe('rev1'); + expect(dp.getLastModifiedDate()).toBe(global.Date.mock.instances[0]); + expect(dp.getLastNumModifiedFiles()).toBe(3); + expect(dp.getAllModules()).toEqual([ + 'pre0', + '__d(1.1);', + '__d(2);', + '__d(3);', + 'post0', + ]); + }); });