Skip to content

Commit 7402027

Browse files
Redux devtools trace + source map (#524)
* Implement trace feature of redux-devtools * Implement sourceMap for redux-devtools trace * Feat: Add patch redux-devtools-trace-monitor to open file Co-authored-by: Jhen <[email protected]>
1 parent f4979b2 commit 7402027

File tree

5 files changed

+159
-9
lines changed

5 files changed

+159
-9
lines changed

app/worker/reduxAPI.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
filterStagedActions,
1616
filterState,
1717
} from 'redux-devtools-core/lib/utils/filters';
18+
import { updateStackWithSourceMap } from './utils';
1819

1920
function configureStore(next, subscriber, options) {
2021
return instrument(subscriber, options)(next);
@@ -30,6 +31,41 @@ let listenerAdded;
3031
let locked;
3132
let paused;
3233

34+
function getStackTrace(config, toExcludeFromTrace) {
35+
if (!config.trace) return undefined;
36+
if (typeof config.trace === 'function') return config.trace();
37+
38+
let stack;
39+
let extraFrames = 0;
40+
let prevStackTraceLimit;
41+
const traceLimit = config.traceLimit;
42+
const error = Error();
43+
if (Error.captureStackTrace) {
44+
if (Error.stackTraceLimit < traceLimit) {
45+
prevStackTraceLimit = Error.stackTraceLimit;
46+
Error.stackTraceLimit = traceLimit;
47+
}
48+
Error.captureStackTrace(error, toExcludeFromTrace);
49+
} else {
50+
extraFrames = 3;
51+
}
52+
stack = error.stack;
53+
if (prevStackTraceLimit) Error.stackTraceLimit = prevStackTraceLimit;
54+
if (
55+
extraFrames ||
56+
typeof Error.stackTraceLimit !== 'number' ||
57+
Error.stackTraceLimit > traceLimit
58+
) {
59+
const frames = stack.split('\n');
60+
if (frames.length > traceLimit) {
61+
stack = frames
62+
.slice(0, traceLimit + extraFrames + (frames[0] === 'Error' ? 1 : 0))
63+
.join('\n');
64+
}
65+
}
66+
return updateStackWithSourceMap(stack);
67+
}
68+
3369
function getLiftedState(store, filters) {
3470
return filterStagedActions(store.liftedStore.getState(), filters);
3571
}
@@ -67,6 +103,7 @@ function relay(type, state, instance, action, nextActionId) {
67103
);
68104
}
69105
if (type === 'ACTION') {
106+
action.stack = getStackTrace(instance, true);
70107
message.action = stringify(
71108
!actionSanitizer ? action : actionSanitizer(action.action, nextActionId - 1),
72109
serializeAction
@@ -236,6 +273,8 @@ export default function devToolsEnhancer(options = {}) {
236273
deserializeAction,
237274
serialize,
238275
predicate,
276+
trace,
277+
traceLimit,
239278
} = options;
240279
const id = generateId(options.instanceId);
241280

@@ -269,6 +308,8 @@ export default function devToolsEnhancer(options = {}) {
269308
serializeAction,
270309
serialize,
271310
predicate,
311+
trace,
312+
traceLimit,
272313
};
273314

274315
start(instances[id]);

app/worker/utils.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,19 @@ export const ignoreRNDIntervalSpy = async (
138138
}
139139
};
140140
};
141+
142+
143+
const RN_DEBUGGER_URL_PART = 'RNDebuggerWorker.js';
144+
const BUNDLE_URL_REGEXP = /(http[\S]*?index\.bundle\?[\S]*?)(:\d+:?\d?)/;
145+
146+
const addInlineSourceMap = (_, urlGroup1, urlGroup2) =>
147+
`${urlGroup1}&inlineSourceMap=true${urlGroup2}`;
148+
const mapStackLines = line => line.replace(BUNDLE_URL_REGEXP, addInlineSourceMap);
149+
const filterRnDebuggerLines = line => !line.includes(RN_DEBUGGER_URL_PART);
150+
151+
export function updateStackWithSourceMap(stack) {
152+
const lines = stack.split('\n');
153+
const linesWithoutRNDebugger = lines.filter(filterRnDebuggerLines);
154+
const lineWithSourceMap = linesWithoutRNDebugger.map(mapStackLines);
155+
return lineWithSourceMap.join('\n');
156+
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@
9191
"react-dom": "^15.6.1",
9292
"react-redux": "^5.0.7",
9393
"redux": "^3.7.2",
94-
"redux-devtools": "^3.4.1",
94+
"redux-devtools": "^3.5.0",
9595
"redux-devtools-core": "^0.2.1",
96-
"redux-devtools-instrument": "^1.9.0",
96+
"redux-devtools-instrument": "^1.9.4",
9797
"redux-persist": "^4.10.2",
98-
"remotedev-app": "^0.10.8",
98+
"remotedev-app": "^0.10.13-beta",
9999
"remotedev-monitor-components": "^0.0.5",
100100
"remotedev-slider": "^1.1.3"
101101
},
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
diff --git a/node_modules/redux-devtools-trace-monitor/lib/openFile.js b/node_modules/redux-devtools-trace-monitor/lib/openFile.js
2+
index 3d6cc6a..e4d1f87 100644
3+
--- a/node_modules/redux-devtools-trace-monitor/lib/openFile.js
4+
+++ b/node_modules/redux-devtools-trace-monitor/lib/openFile.js
5+
@@ -97,33 +97,5 @@ function openInEditor(editor, path, stackFrame) {
6+
}
7+
8+
function openFile(fileName, lineNumber, stackFrame) {
9+
- if (process.env.NODE_ENV === 'development') // eslint-disable-next-line no-console
10+
- console.log(fileName, lineNumber, stackFrame);
11+
- if (!chrome || !chrome.storage) return; // TODO: Pass editor settings for using outside of browser extension
12+
-
13+
- var storage = isFF ? chrome.storage.local : chrome.storage.sync || chrome.storage.local;
14+
- storage.get(['useEditor', 'editor', 'projectPath'], function (_ref) {
15+
- var useEditor = _ref.useEditor,
16+
- editor = _ref.editor,
17+
- projectPath = _ref.projectPath;
18+
-
19+
- if (useEditor && projectPath && typeof editor === 'string' && /^\w{1,30}$/.test(editor)) {
20+
- openInEditor(editor.toLowerCase(), projectPath, stackFrame);
21+
- } else {
22+
- if (chrome.devtools && chrome.devtools.panels && chrome.devtools.panels.openResource) {
23+
- openResource(fileName, lineNumber, stackFrame);
24+
- } else if (chrome.runtime && (chrome.runtime.openOptionsPage || isFF)) {
25+
- if (chrome.devtools && isFF) {
26+
- chrome.devtools.inspectedWindow.eval('confirm("Set the editor to open the file in?")', function (result) {
27+
- if (!result) return;
28+
- chrome.runtime.sendMessage({
29+
- type: 'OPEN_OPTIONS'
30+
- });
31+
- });
32+
- } else if (confirm('Set the editor to open the file in?')) {
33+
- chrome.runtime.openOptionsPage();
34+
- }
35+
- }
36+
- }
37+
- });
38+
+ window.openInEditor(fileName, lineNumber)
39+
}

yarn.lock

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
dependencies:
1515
"@babel/highlight" "7.0.0-beta.44"
1616

17+
"@babel/code-frame@^7.0.0":
18+
version "7.10.4"
19+
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
20+
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
21+
dependencies:
22+
"@babel/highlight" "^7.10.4"
23+
1724
"@babel/code-frame@^7.0.0-beta.35":
1825
version "7.5.5"
1926
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
@@ -55,6 +62,11 @@
5562
dependencies:
5663
"@babel/types" "7.0.0-beta.44"
5764

65+
"@babel/helper-validator-identifier@^7.10.4":
66+
version "7.10.4"
67+
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
68+
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
69+
5870
5971
version "7.0.0-beta.44"
6072
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5"
@@ -73,6 +85,15 @@
7385
esutils "^2.0.2"
7486
js-tokens "^4.0.0"
7587

88+
"@babel/highlight@^7.10.4":
89+
version "7.10.4"
90+
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
91+
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
92+
dependencies:
93+
"@babel/helper-validator-identifier" "^7.10.4"
94+
chalk "^2.0.0"
95+
js-tokens "^4.0.0"
96+
7697
"@babel/runtime@^7.1.2":
7798
version "7.7.7"
7899
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf"
@@ -522,6 +543,11 @@ almost-equal@^1.1.0:
522543
resolved "https://registry.yarnpkg.com/almost-equal/-/almost-equal-1.1.0.tgz#f851c631138757994276aa2efbe8dfa3066cccdd"
523544
integrity sha1-+FHGMROHV5lCdqou++jfowZszN0=
524545

546+
anser@^1.4.7:
547+
version "1.4.9"
548+
resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760"
549+
integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA==
550+
525551
ansi-colors@^3.0.0:
526552
version "3.2.4"
527553
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
@@ -8971,6 +8997,15 @@ react@^15.1.0, react@^15.6.1:
89718997
object-assign "^4.1.0"
89728998
prop-types "^15.5.10"
89738999

9000+
react@^16.4.0:
9001+
version "16.13.1"
9002+
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
9003+
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
9004+
dependencies:
9005+
loose-envify "^1.1.0"
9006+
object-assign "^4.1.1"
9007+
prop-types "^15.6.2"
9008+
89749009
react@^16.8.2:
89759010
version "16.9.0"
89769011
resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa"
@@ -9145,7 +9180,7 @@ redux-devtools-core@^0.2.1:
91459180
nanoid "^2.0.0"
91469181
remotedev-serialize "^0.1.8"
91479182

9148-
redux-devtools-instrument@^1.9.0:
9183+
redux-devtools-instrument@^1.9.0, redux-devtools-instrument@^1.9.4:
91499184
version "1.9.6"
91509185
resolved "https://registry.yarnpkg.com/redux-devtools-instrument/-/redux-devtools-instrument-1.9.6.tgz#6b412595f74b9d48cfd4ecc13e585b1588ed6e7e"
91519186
integrity sha512-MwvY4cLEB2tIfWWBzrUR02UM9qRG2i7daNzywRvabOSVdvAY7s9BxSwMmVRH1Y/7QWjplNtOwgT0apKhHg2Qew==
@@ -9184,7 +9219,20 @@ redux-devtools-themes@^1.0.0:
91849219
dependencies:
91859220
base16 "^1.0.0"
91869221

9187-
redux-devtools@^3.0.0, redux-devtools@^3.4.1:
9222+
redux-devtools-trace-monitor@^0.1.0:
9223+
version "0.1.1"
9224+
resolved "https://registry.yarnpkg.com/redux-devtools-trace-monitor/-/redux-devtools-trace-monitor-0.1.1.tgz#a7847424a742d00d2bd31cb971a27f31f3e0cf6f"
9225+
integrity sha512-DtcOi/hxo5W4nyBScmuDCShso1EfsjZ8DubylGlkZ1vnU84rN2NUBZCyhrFyskoC2rpXbwdbgp/D6MAE0cUQlg==
9226+
dependencies:
9227+
"@babel/code-frame" "^7.0.0"
9228+
anser "^1.4.7"
9229+
chalk "^2.4.1"
9230+
html-entities "^1.2.1"
9231+
react "^16.4.0"
9232+
redux-devtools-themes "^1.0.0"
9233+
settle-promise "^1.0.0"
9234+
9235+
redux-devtools@^3.0.0, redux-devtools@^3.5.0:
91889236
version "3.5.0"
91899237
resolved "https://registry.yarnpkg.com/redux-devtools/-/redux-devtools-3.5.0.tgz#d69ab76d4f0f8abdf6d24bcf5954d7a1aa2b6827"
91909238
integrity sha512-pGU8TZNvWxPaCCE432AGm6H6alQbAz80gQM5CzM3SjX9/oSNu/HPF17xFdPQJOXasqyih1Gv167kZDTRe7r0iQ==
@@ -9293,10 +9341,10 @@ regjsparser@^0.1.4:
92939341
dependencies:
92949342
jsesc "~0.5.0"
92959343

9296-
remotedev-app@^0.10.8:
9297-
version "0.10.12"
9298-
resolved "https://registry.yarnpkg.com/remotedev-app/-/remotedev-app-0.10.12.tgz#0f46847635c4cade6b925749fcf6c3c5d4f050c9"
9299-
integrity sha512-hwgL0ik5La9Ct2Juwgej9xixuT1VBLEosWih68zzipatN4K6Pw5PEJ9cSCdrGzbHjETzejisRE615xtm337T4Q==
9344+
remotedev-app@^0.10.13-beta:
9345+
version "0.10.13-beta"
9346+
resolved "https://registry.yarnpkg.com/remotedev-app/-/remotedev-app-0.10.13-beta.tgz#e240a10c9184fdca5fee68a36078eed313883aa7"
9347+
integrity sha512-QtbHdZg9kcVIH1/jBvq8jOd5okA+mRnx6zLP2O7eN3PTYpRvzRKpHKavNUTcFfjJgo94URqeAqpf/ZJ+y+SKhg==
93009348
dependencies:
93019349
chrome-storage-local "^0.1.6"
93029350
d3-state-visualizer "^1.3.1"
@@ -9315,6 +9363,7 @@ remotedev-app@^0.10.8:
93159363
redux-devtools-log-monitor "^1.2.0"
93169364
redux-devtools-test-generator "^0.4.0"
93179365
redux-devtools-themes "^1.0.0"
9366+
redux-devtools-trace-monitor "^0.1.0"
93189367
remotedev-inspector-monitor "^0.11.0"
93199368
remotedev-monitor-components "^0.0.5"
93209369
remotedev-slider "1.1.3"
@@ -9883,6 +9932,11 @@ [email protected]:
98839932
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
98849933
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
98859934

9935+
settle-promise@^1.0.0:
9936+
version "1.0.0"
9937+
resolved "https://registry.yarnpkg.com/settle-promise/-/settle-promise-1.0.0.tgz#697adb58b821f387ce2757c06efc9de5f0ee33d8"
9938+
integrity sha1-aXrbWLgh84fOJ1fAbvyd5fDuM9g=
9939+
98869940
sha.js@^2.4.0, sha.js@^2.4.8:
98879941
version "2.4.11"
98889942
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"

0 commit comments

Comments
 (0)