Skip to content

Commit 11a919b

Browse files
authored
Added debugging docs (#3446)
## Description Introducing a new article to the documentation under the `Guides` section titled `Debugging Reanimated`. The article explains which tools can be used for debugging React Native apps running the Reanimated module and the limitations of each solution. ## Screenshot <img width="782" alt="image" src="https://user-images.githubusercontent.com/10947344/191734502-39594b86-2b49-4bb0-b994-45dd2c7dd992.png"> ## Checklist - [ ] Included code example that can be used to test this change - [ ] Updated TS types - [ ] Added TS types tests - [ ] Added unit / integration tests - [x] Updated documentation - [x] Ensured that CI passes
1 parent 6985391 commit 11a919b

22 files changed

Lines changed: 3289 additions & 2024 deletions

File tree

.github/workflows/docs-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ jobs:
2121
- name: Install node dependencies
2222
working-directory: ${{ env.WORKING_DIRECTORY }}
2323
run: yarn
24+
- name: Lint check docs
25+
working-directory: ${{ env.WORKING_DIRECTORY }}
26+
run: yarn lint
2427
- name: Build docs
2528
working-directory: ${{ env.WORKING_DIRECTORY }}
2629
run: yarn build

docs/.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module.exports = {
22
root: true,
3-
extends: '../.eslintrc.js',
3+
extends: ['plugin:mdx/recommended'],
44
};

docs/docs/guide/debugging.mdx

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
---
2+
id: debugging
3+
title: "Debugging Reanimated"
4+
sidebar_label: "Debugging Reanimated"
5+
---
6+
7+
import {
8+
SummaryTable,
9+
ChromeDebuggerTable,
10+
ChromeDevToolsTable,
11+
FlipperTable,
12+
SafariDevToolsTable,
13+
ReactDeveloperToolsTable,
14+
} from './debugging_tables/tables';
15+
16+
Due to Reanimated's unique architecture and usage of a second JS runtime, debugging
17+
can be problematic, and some common solutions might not work as expected.
18+
This article summarizes all the available methods and highlights their caveats.
19+
20+
:::info
21+
22+
Reanimated v1 works with all the common React Native debugging tools. This
23+
article focuses on the use of these tools with Reanimated v2.
24+
25+
:::
26+
27+
### React Native debugging tools
28+
29+
These are the debugging tools we checked for compatibility with React Native
30+
apps using the Reanimated library:
31+
32+
- [**Chrome debugger**](https://reactnative.dev/docs/debugging#chrome-developer-tools)
33+
(also known as the _React Native Debugger_) is a simple tool that creates a web
34+
worker inside your preferred browser which executes your app's JavaScript code. It works
35+
with all the runtimes available in React Native.
36+
37+
- [**Chrome DevTools**](https://reactnative.dev/docs/hermes#debugging-js-on-hermes-using-google-chromes-devtools)
38+
(unavailable for JSC) is Chrome's built-in feature that allows for connecting to a
39+
remote JavaScript runtime. This means that the code you are debugging actually
40+
runs on the device itself and behaves the same way as it would with DevTools detached.
41+
42+
- [**Flipper**](https://fbflipper.com/) (Hermes debugger) is an app created by
43+
Facebook that makes it easy to use the _Chrome DevTools_ while providing additional tools for
44+
UI inspection and debugging.
45+
46+
- [**Safari DevTools**](https://reactnative.dev/docs/debugging#safari-developer-tools)
47+
is Safari's built-in feature that is only available for iOS devices running JSC. It works
48+
very similarly to Chrome DevTools - it allows you to connect to a remote runtime
49+
and keep code execution on device.
50+
51+
- [**React Developer Tools**](https://reactnative.dev/docs/debugging#react-developer-tools)
52+
are a standalone app that allows debugging UI through the inspector, as well as monitoring
53+
performance and profiling your app.
54+
55+
### The JS context vs. the UI context
56+
57+
It is important to understand the differences between the JS and UI contexts.
58+
One thing to note is that adding Reanimated changes nothing when it comes
59+
to debugging the regular JS context that is available in all React Native apps.
60+
It is only debugging the UI context, which is specific to the Reanimated
61+
library that might be difficult to debug in some scenarios, which are all
62+
explained in this article.
63+
64+
You can read more about Reanimated's architecture [here](../fundamentals/architecture).
65+
66+
### Debugging web apps
67+
68+
For debugging web apps, you may use the tools you prefer or any that are provided
69+
by the browser of your choice. We did not discover any issues with debugging
70+
apps using Reanimated on web.
71+
72+
### Summary
73+
74+
<SummaryTable />
75+
76+
:::caution
77+
78+
Remember that console logs will always appear in the primary JS runtime as the
79+
`console.log` function on the UI runtime is just a wrapper around the one from
80+
the JS runtime.
81+
82+
:::
83+
84+
### Chrome Debugger
85+
86+
<ChromeDebuggerTable />
87+
88+
**Summary:**
89+
Works, but uses web implementations of functions and runs everything on the JS thread.
90+
91+
Since the Chrome Debugger runs its own web worker, all the code is run on
92+
the JS thread, and it uses the JavaScript engine provided by your web
93+
browser (V8 in Chrome, JSC in Safari and SpiderMonkey in Firefox). This
94+
means that this piece of code:
95+
96+
```js
97+
function runWorklet() {
98+
'worklet';
99+
console.log('worklet:', _WORKLET);
100+
}
101+
runOnUI(runWorklet)();
102+
```
103+
104+
would output:
105+
106+
```
107+
LOG: worklet: false
108+
```
109+
110+
Another side effect is that Reanimated uses web implementations of all
111+
functions. This means that the `scrollTo` function will work
112+
(using the native web implementation), but the `measure`
113+
function will not be available, and its usage will trigger this error:
114+
115+
```
116+
[Reanimated] measure() cannot be used for web or Chrome Debugger
117+
```
118+
119+
You may still use the standard web version of `measure` as described
120+
[here](../api/nativeMethods/measure).
121+
122+
Those functions that are provided by Reanimated and do not have web
123+
implementations won't work at all.
124+
An example of this behavior is the `useAnimatedSensor` hook,
125+
which currently only works on mobile platforms. When debugging in Chrome and using
126+
this hook, the following message will appear in the logs:
127+
128+
```
129+
[Reanimated] useAnimatedSensor is not available on web yet.
130+
```
131+
132+
But despite all of this, it is still possible to set breakpoints both in
133+
normal JS code and in worklets (since they run on the main JS
134+
thread now).
135+
136+
### Chrome DevTools
137+
138+
<ChromeDevToolsTable />
139+
140+
**Summary:**
141+
Works and both contexts can be debugged.
142+
143+
:::warning
144+
145+
This is an early experimental feature.
146+
147+
:::
148+
149+
Worklet debugging is now available in Reanimated apps as an early experimental
150+
feature. We do not recommend using Chrome DevTools to debug the UI context, but
151+
instead try using the Flipper tool. It has fewer bugs and provides a much better
152+
experience.
153+
154+
If you still want to use Chrome DevTools then follow these steps:
155+
156+
1. Add the `patch-package` to your project and set it up to run as a `post-install` task.
157+
More details can be found [here](https://www.npmjs.com/package/patch-package).
158+
159+
2. Add the necessary patches to the `patches/` folder:
160+
161+
- [this](/content/metro-inspector-proxy+0.72.1.patch) patch for `metro-inspector-proxy`,
162+
- [this](/content/react-native-gesture-handler+2.5.0.patch) one for `react-native-gesture-handler`
163+
(not necessary for `react-native-gesture-handler` 2.7.0 or newer).
164+
165+
*Warnings about mismatched patch versions can be safely ignored if the patch was successfully applied.*
166+
167+
3. Open [chrome://inspect](chrome://inspect) in a Google Chrome browser.
168+
169+
4. Select the Reanimated runtime from the list. The list should look something
170+
like this:
171+
172+
![Screenshot showing Chrome DevTools target selection](/img/debugging/ChromeDevToolsList.png)
173+
174+
You may choose either `Reanimated Runtime` or `Reanimated Runtime experimental
175+
(Improved Chrome Reloads)`, but we recommend the latter.
176+
177+
_Debugging relies on source maps that are generated by the Reanimated Babel plugin, so you
178+
might have to run `yarn start --reset-cache` for those changes to take effect.
179+
In case it still doesn't work after that please reinstall the app and reset metro
180+
cache once again._
181+
182+
:::caution
183+
184+
Known issues include:
185+
186+
- Reloads don't work - if a debugger is connected to the Reanimated runtime while
187+
the reload is performed, the app will crash (both on Android and iOS)
188+
189+
- On iOS, a breakpoint can't be set in a line where a breakpoint was previously
190+
set and then removed
191+
192+
- On iOS, breakpoint labels are not visible
193+
194+
- The profiler does not work (it is not possible to stop the recording) - this is an issue with Hermes and is not related
195+
to Reanimated and has been already fixed in this [PR](https://github.com/facebook/react-native/pull/34129)
196+
197+
- The console is unresponsive if there are no animations running (this will be fixed in the near future)
198+
199+
These issues **do not** affect release builds as well as debug builds where the debugger connection
200+
is closed while performing a reload or the debugger is not used at all.
201+
202+
:::
203+
204+
*We are actively working on improving the debugging experience with Chrome DevTools on Hermes.*
205+
206+
### Flipper (Hermes debugger)
207+
208+
<FlipperTable />
209+
210+
**Summary:**
211+
Works and both contexts can be debugged.
212+
213+
:::warning
214+
215+
This is an early experimental feature.
216+
217+
:::
218+
219+
Worklet debugging is now available in Reanimated apps as an early experimental
220+
feature. If you want to try it out follow these steps:
221+
222+
1. Add the `patch-package` to your project and set it up to run as a `post-install` task.
223+
More details can be found [here](https://www.npmjs.com/package/patch-package);
224+
225+
2. Add the necessary patches to the `patches/` folder:
226+
227+
- [this](/content/metro-inspector-proxy+0.72.1.patch) patch for `metro-inspector-proxy`,
228+
- [this](/content/react-native-gesture-handler+2.5.0.patch) one for `react-native-gesture-handler`
229+
(not necessary for `react-native-gesture-handler` 2.7.0 or newer).
230+
231+
*Warnings about mismatched patch versions can be safely ignored if the patch was successfully applied.*
232+
233+
3. Install the `reanimated` plugin in Flipper.
234+
235+
![Screenshot showing where the plugin management panel is in Flipper](/img/debugging/flipper1.png)
236+
![Screenshot showing where the install button for plugins is](/img/debugging/flipper2.png)
237+
238+
4. Select the plugin from the side menu (it might be disabled) and you should
239+
be good to go!
240+
241+
![Screenshot showing the plugin working](/img/debugging/flipper3.png)
242+
243+
_Debugging relies on source maps that are generated by the Reanimated Babel plugin, so you
244+
might have to run `yarn start --reset-cache` for those changes to take effect.
245+
In case it still doesn't work after that please reinstall the app and reset metro
246+
cache once again._
247+
248+
:::caution
249+
250+
Known issues include:
251+
252+
- Reloads don't work - if a debugger is connected to the Reanimated runtime while
253+
the reload is performed, the app will crash (both on Android and iOS)
254+
255+
- Breakpoints might not be active after a reload even though they look as if they
256+
were
257+
258+
- Android app crashes after the Flipper client is closed and will crash on startup
259+
after that. This is a known Flipper issue ([link](https://github.com/facebook/flipper/issues/3026))
260+
and is not related to Reanimated.
261+
262+
- The profiler does not work (it is not possible to stop the recording) - this is an issue with Hermes and is not related
263+
to Reanimated and has been already fixed in this [PR](https://github.com/facebook/react-native/pull/34129)
264+
265+
- The console is unresponsive if there are no animations running (this will be fixed in the near future)
266+
267+
These issues **do not** affect release builds as well as debug builds where the debugger connection
268+
is closed while performing a reload or the debugger is not used at all.
269+
270+
:::
271+
272+
*We are actively working on improving the debugging experience with Flipper on Hermes.*
273+
274+
### Safari DevTools
275+
276+
<SafariDevToolsTable />
277+
278+
**Summary:**
279+
Safari DevTools is only available on iOS devices running the JSC engine.
280+
Worklet debugging is available.
281+
282+
After opening Safari and configuring it as specified in the React Native
283+
docs, under `Develop > Device` you'll see two JSC contexts
284+
like in the screenshot below:
285+
286+
![Screenshot showing Safari's Develop menu options](/img/debugging/SafariJSCiOS.png)
287+
288+
The order of the contexts is random, but one of them will be the main JS context.
289+
All `console.log` outputs will appear in the console of this context. You can also
290+
set breakpoints here, but unfortunately the only source file visible is the
291+
transformed `indexjs.bundle` which does make things more difficult to find.
292+
293+
The other option will be the UI context. No console logs will appear in
294+
the console of this context, but all worklet functions should be visible
295+
as separate files. It is also possible to set breakpoints in these
296+
worklets.
297+
298+
### React Developer Tools
299+
300+
<ReactDeveloperToolsTable />
301+
302+
**Summary:**
303+
React Developer Tools work as expected, and the profiler and layout inspector can
304+
be used as usual.
305+
306+
On Android, remember to first run the command:
307+
```
308+
adb reverse tcp:8097 tcp:8097
309+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.width10 {
2+
width: 10%;
3+
}
4+
5+
.width20 {
6+
width: 20%;
7+
}
8+
9+
.width30 {
10+
width: 30%;
11+
}
12+
13+
.cellNormal {
14+
text-align: center;
15+
}
16+
17+
.cellNotAvailable {
18+
text-align: center;
19+
color: lightgray;
20+
}

0 commit comments

Comments
 (0)