Skip to content

Commit

Permalink
docs: Add metro config wrapper and reanimated logger docs (#6467)
Browse files Browse the repository at this point in the history
## Summary

This PR adds pages in docs for the new metro config wrapper and custom
logger configuration.

It also changes logger configuration to use the `strict` mode by default
and adds a reference to docs for those would would like to disable
strict mode warnings.

I spotted an issue with `configureReanimatedLogger` on the web, as there
is no `executeOnUIRuntimeSync` in JSReanimated, so I added the necessary
check in there as well.

## Examples

### Metro config docs

![Screenshot 2024-08-30 at 17 04
58](https://github.com/user-attachments/assets/eaa6965f-ef3f-4130-817d-4ec29cc342e3)

### Logger config docs

![Screenshot 2024-08-30 at 17 04
40](https://github.com/user-attachments/assets/6402b537-38f6-4316-b209-0273be0dca62)

### Adjusted message for `strict` mode warnings

<img
src="https://github.com/user-attachments/assets/1f1c068b-3a76-4978-8609-843eb9f20ac5"
width="300" />

## Test plan

Open docs locally and navigate to the new **Debugging** section.

---------

Co-authored-by: Kacper Kapuściak <39658211+kacperkapusciak@users.noreply.github.com>
Co-authored-by: Tomasz Żelawski <40713406+tjzel@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 11, 2024
1 parent c129644 commit 6ed8aca
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 3 deletions.
7 changes: 7 additions & 0 deletions packages/docs-reanimated/docs/debugging/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Debugging",
"position": 120,
"link": {
"type": "generated-index"
}
}
59 changes: 59 additions & 0 deletions packages/docs-reanimated/docs/debugging/accurate-call-stacks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
id: accurate-call-stacks
sidebar_label: Accurate Call Stacks
sidebar_position: 1
---

# Accurate Call Stacks

When debugging Reanimated code, you may encounter error or warning call stacks that don't clearly indicate the root cause of the problem. These stacks can be misleading, as they often highlight code from Reanimated's internals rather than the misuse of the Reanimated API that is the source of the problem.

To address this, Reanimated provides a Metro configuration wrapper called `wrapWithReanimatedMetroConfig`. This wrapper automatically adjusts your Metro config to improve the accuracy of call stacks in warnings and errors generated by the Reanimated library.

<details>
<summary>How does it work?</summary>

By default, React Native displays the entire call stack up to the point where an error is thrown or a warning is logged, including all stack frames except those from the React Native source code.

To modify this behavior, we can use the `symbolicator` field in the Metro config, which allows customization of the displayed stack frames. Reanimated leverages this feature to adjust which stack frames are **hidden** (**collapsed**) in the stack trace. By doing so, stack frames from Reanimated internals are hidden, ensuring that the stack trace only highlights the relevant parts of the call stack.

</details>

## Reference

To enable more accurate call stacks, simply import `wrapWithReanimatedMetroConfig` from `react-native-reanimated/metro-config` and wrap your existing Metro configuration in the `metro.config.js` file with it.

```js
// metro.config.js
const {
wrapWithReanimatedMetroConfig,
} = require('react-native-reanimated/metro-config');

const config = {
// Your existing Metro configuration options
};

module.exports = wrapWithReanimatedMetroConfig(config);
```

## Example

The following example shows the difference in call stacks before and after applying the Reanimated Metro config wrapper. The **Before** image displays Reanimated source code as the error source, while the **After** image shows the actual incorrect code that caused the error.

| Before | After |
| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| ![Call Stack before applying Reanimated Metro config wrapper](/img/debugging/MetroConfigBefore.png) | ![Call Stack after applying Reanimated Metro config wrapper](/img/debugging/MetroConfigAfter.png) |

## Remarks

- The `wrapWithReanimatedMetroConfig` doesn't remove any stack frames from the call stack; it only collapses irrelevant frames from Reanimated. If you want to inspect them, you can expand collapsed stack frames by pressing on the **See N more frames** text at the bottom of the **Call Stack**.

<Indent>

| Collapsed | Expanded |
| -------------------------------------------------------------- | ------------------------------------------------------------ |
| ![Collapsed Call Stack](/img/debugging/CollapsedCallStack.png) | ![Expanded Call Stack](/img/debugging/ExpandedCallStack.png) |

</Indent>

- Some errors, particularly from asynchronous code, may still result in stack traces pointing to Reanimated internals instead of the exact problematic line in your code. This occurs because stack traces lose track of the original code that initiated the asynchronous operation. In such a case, you'll need to manually debug the issue based on the error message to identify the potential cause of the problem.
69 changes: 69 additions & 0 deletions packages/docs-reanimated/docs/debugging/logger-configuration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
id: logger-configuration
sidebar_label: Logger configuration
sidebar_position: 2
---

# Logger configuration

Reanimated shows warnings that indicate misuses of the library API, such as modifying the [shared value](/docs/fundamentals/glossary#shared-value) during component re-render. These logs can be configured to be more or less verbose.

The **default** logger configuration doesn't require any user setup and displays **all warnings and errors**. If you want to change this behavior, use the `configureReanimatedLogger` function.

## Reference

To modify the default Reanimated logger configuration, import `configureReanimatedLogger` from `react-native-reanimated` and call it with the desired configuration.

```js
import {
configureReanimatedLogger,
ReanimatedLogLevel,
} from 'react-native-reanimated';

// This is the default configuration
configureReanimatedLogger({
level: ReanimatedLogLevel.warn,
strict: true, // Reanimated runs in strict mode by default
});
```

<details>
<summary>Type definitions</summary>

```typescript
function configureReanimatedLogger(config: LoggerConfig): void;

type LoggerConfig = {
level?: ReanimatedLogLevel;
strict?: boolean;
};

enum ReanimatedLogLevel {
warn = 1,
error = 2,
}
```

</details>

### Configuration options

#### `level`

A value of the `ReanimatedLogLevel` enum that defines the **minimum level** of the logs that will be shown.

#### `strict`

A boolean value that enables or disables **strict** mode. When **strict** mode is enabled, Reanimated will show more warnings that can help you to catch potential issues in your code.

## Remarks

- The logger configuration is global and affects all warnings and errors displayed by Reanimated. There's no option to configure the logger per file/component.

- The `configureReanimatedLogger` function should be called before any Reanimated animations are created, e.g. in the root file of your app.

- The `configureReanimatedLogger` function is intended for application developers. If you are creating a library that relies on Reanimated, don't include this function call in your library source code - users will inherit the configuration which will override the default configuration in the Reanimated library.

## Platform compatibility

<PlatformCompatibility android ios web />
28 changes: 27 additions & 1 deletion packages/docs-reanimated/docs/fundamentals/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,33 @@ To learn more about the plugin head onto to [Reanimated babel plugin](/docs/fund

</details>

### Step 3: Clear Metro bundler cache (recommended)
### Step 3: Wrap metro config with reanimated wrapper (recommended)

Wrap your existing Metro configuration in the `metro.config.js` file with the `wrapWithReanimatedMetroConfig` function.

```js
// metro.config.js
const {
wrapWithReanimatedMetroConfig,
} = require('react-native-reanimated/metro-config');

const config = {
// Your existing Metro configuration options
};

module.exports = wrapWithReanimatedMetroConfig(config);
```

<details>
<summary>Why should I do this?</summary>

Wrapping your Metro configuration with the Reanimated Metro config wrapper will result in displaying improved reanimated errors and warnings with more accurate call stacks. Thanks to this, identifying misuses of the Reanimated API will be much easier than before.

To learn more about this feature, head onto to [Accurate Call Stacks](/docs/debugging/accurate-call-stacks).

</details>

### Step 4: Clear Metro bundler cache (recommended)

<Tabs groupId="package-managers">
<TabItem value="expo" label="EXPO" default>
Expand Down
2 changes: 1 addition & 1 deletion packages/docs-reanimated/docs/guides/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Guides",
"position": 120,
"position": 130,
"link": {
"type": "generated-index"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Reanimated Babel plugin",
"position": 130,
"position": 140,
"link": {
"type": "generated-index"
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions packages/react-native-reanimated/src/logger/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import { addLogBoxLog } from './LogBox';
import type { LogData, LogBoxLogLevel } from './LogBox';

const DOCS_URL =
'https://docs.swmansion.com/react-native-reanimated/docs/debugging/logger-configuration';
const DOCS_REFERENCE = `If you don't want to see this message, you can disable the \`strict\` mode. Refer to:\n${DOCS_URL} for more details.`;

type LogFunction = (data: LogData) => void;

export enum LogLevel {
Expand Down Expand Up @@ -131,6 +135,11 @@ function handleLog(
) {
return;
}

if (options.strict) {
message += `\n\n${DOCS_REFERENCE}`;
}

config.logFunction(createLog(level, message));
}

Expand Down

0 comments on commit 6ed8aca

Please sign in to comment.