Skip to content

Commit 30e0492

Browse files
authored
chore(Worklets): versioned docs (#9664)
## Summary Adding versioned docs for Worklets. I thought it's a good moment for that since there are a lot of changes to the docs coming with the Bundle Mode becoming the recommended mode and some of its APIs changing. ## Test plan I tested everything locally 👌
1 parent d1ad511 commit 30e0492

61 files changed

Lines changed: 4513 additions & 4 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/docs-worklets/docusaurus.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ const config = {
5353
sidebarCollapsible: false,
5454
editUrl:
5555
'https://github.com/software-mansion/react-native-reanimated/edit/main/docs/docs-worklets',
56-
versions: { current: { label: '0.x' } },
56+
lastVersion: 'current',
57+
versions: {
58+
current: { label: '0.9' },
59+
'0.10': { label: '0.10 (unreleased)', banner: 'unreleased' },
60+
},
5761
},
5862
theme: { customCss: require.resolve('./src/css/index.css') },
5963
}),

docs/docs-worklets/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
"write-translations": "docusaurus write-translations",
1616
"write-heading-ids": "docusaurus write-heading-ids",
1717
"typecheck": "tsc --noEmit",
18-
"lint": "yarn run --top-level oxfmt --check docs src",
19-
"format": "yarn run --top-level oxfmt docs src"
18+
"lint": "yarn run --top-level oxfmt --check docs src versioned_docs",
19+
"format": "yarn run --top-level oxfmt docs src versioned_docs"
2020
},
2121
"dependencies": {
2222
"@babel/core": "7.28.4",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"label": "Bundle Mode",
3+
"position": 2,
4+
"link": {
5+
"type": "generated-index"
6+
}
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
sidebar_position: 1
3+
sidebar_label: Overview
4+
slug: /bundleMode
5+
---
6+
7+
import useBaseUrl from '@docusaurus/useBaseUrl';
8+
import ThemedImage from '@theme/ThemedImage';
9+
10+
<ThemedImage
11+
sources={{
12+
light: useBaseUrl('/img/bundleMode-light.png'),
13+
dark: useBaseUrl('/img/bundleMode-dark.png'),
14+
}}
15+
alt="Bundle Mode conceptual illustration"
16+
/>
17+
18+
# Overview
19+
20+
Bundle Mode is an experimental feature that gives worklets access to your whole JavaScript bundle - meaning that any code that's present in the bundle can be executed in any worklet and on any runtime. This means that third party libraries can be used in worklets without the need to patch them. It's also a performance improvement as worklets' code can benefit from all the optimizations that pre-compiled bytecode offers.
21+
22+
**We envision the Bundle Mode to be the default way of using worklets in the future.**
23+
24+
Instructions on how to enable it can be found [here](/docs/bundleMode/setup).
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
sidebar_position: 2
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
import useBaseUrl from '@docusaurus/useBaseUrl';
8+
import ThemedImage from '@theme/ThemedImage';
9+
10+
# Setup
11+
12+
## Package installation
13+
14+
Install `react-native-worklets` package with the `bundle-mode-preview` tag:
15+
16+
<Tabs groupId="package-managers">
17+
<TabItem value="npm" label="NPM">
18+
```bash
19+
npm i react-native-worklets@bundle-mode-preview
20+
```
21+
</TabItem>
22+
23+
<TabItem value="yarn" label="YARN">
24+
```bash
25+
yarn add react-native-worklets@bundle-mode-preview
26+
```
27+
</TabItem>
28+
</Tabs>
29+
30+
## Configure Babel
31+
32+
To use `react-native-worklets`'s Bundle Mode feature, you need to make the following changes in your repository:
33+
34+
1. **Modify your Babel configuration**. [Worklets Babel Plugin](/docs/worklets-babel-plugin/about) needs to know that it has to prepare your code for the Bundle Mode. This is also the source of truth for your app to know if the Bundle Mode is enabled. In your `babel.config.js` file, add the following:
35+
36+
```javascript {2-5,13}
37+
/** @type {import('react-native-worklets/plugin').PluginOptions} */
38+
const workletsPluginOptions = {
39+
bundleMode: true,
40+
strictGlobal: true, // optional, but recommended
41+
}
42+
43+
module.exports = {
44+
presets: [
45+
... // don't add it here :)
46+
],
47+
plugins: [
48+
...
49+
['react-native-worklets/plugin', workletsPluginOptions],
50+
],
51+
};
52+
```
53+
54+
## Configure Metro
55+
56+
2. **Modify your Metro configuration**. Metro needs to be configured pre-load Bundle Mode entry points into your JavaScript bundle. In your `metro.config.js` file, apply the config required for the bundle mode. For example:
57+
58+
<Tabs groupId="framework">
59+
<TabItem value="expo" label="Expo">
60+
```javascript {3,10}
61+
// Learn more https://docs.expo.io/guides/customizing-metro
62+
const { getDefaultConfig, mergeConfig } = require("expo/metro-config");
63+
const { getBundleModeMetroConfig } = require("react-native-worklets/bundleMode");
64+
65+
@type {import('expo/metro-config').MetroConfig} */
66+
let config = getDefaultConfig(__dirname);
67+
68+
// Your modifications to the config
69+
70+
config = getBundleModeMetroConfig(config);
71+
72+
module.exports = config;
73+
```
74+
</TabItem>
75+
76+
<TabItem value="react-native-community" label="React Native Community">
77+
```javascript {6,12-16}
78+
const {
79+
getDefaultConfig,
80+
mergeConfig,
81+
} = require('@react-native/metro-config');
82+
83+
const { bundleModeMetroConfig } = require('react-native-worklets/bundleMode');
84+
85+
const config = {
86+
// Your Metro config
87+
};
88+
89+
module.exports = mergeConfig(
90+
getDefaultConfig(__dirname),
91+
bundleModeMetroConfig,
92+
config
93+
);
94+
```
95+
</TabItem>
96+
</Tabs>
97+
98+
## Enable seamless Metro bundling
99+
100+
_This step is optional but highly recommended._
101+
102+
If you run the app after just executing the above steps, you will see an error "Failed to get the SHA-1 for ...":
103+
104+
<ThemedImage
105+
sources={{
106+
light: useBaseUrl('/img/sha-light.png'),
107+
dark: useBaseUrl('/img/sha-dark.png'),
108+
}}
109+
alt="Bundle Mode Metro error logs"
110+
/>
111+
112+
This is due to fact that Bundle Mode isolates each worklet in a separate module (file) on the fly and the Metro bundler doesn't index these isolated modules in time.
113+
114+
To fix this issue you can do one of the following:
115+
116+
1. Reload the app and Metro a couple of times until Metro picks up all the new modules. You will have to do it each time. Not recommended.
117+
1. Patch `metro` package for it to synchronously index new modules created by Bundle Mode. This is the recommended approach. **This patch does not require building React Native from source**. You can find patching instructions in the [Worklets repository](https://github.com/software-mansion/react-native-reanimated/tree/main/packages/react-native-worklets/bundleMode/patches).
118+
119+
This patch is a temporary workaround until necessary changes are merged into Metro.
120+
121+
## Enable fast refresh on Worklet Runtimes
122+
123+
_This step is optional but highly recommended._
124+
125+
React Native's Fast Refresh (hot reload) feature doesn't apply to Worklet Runtimes out of the box. Therefore, when you change worklet's code you will see an error "\[Worklets] Unable to resolve worklet with hash ...".
126+
127+
<ThemedImage
128+
sources={{
129+
light: useBaseUrl('/img/hot-light.png'),
130+
dark: useBaseUrl('/img/hot-dark.png'),
131+
}}
132+
alt="Bundle Mode Fast Refresh error logs"
133+
/>
134+
135+
This is due to fact that the Fast Refresh update wasn't sent to the Worklet Runtime and it doesn't know that new worklet with the given hash exists.
136+
137+
To fix this issue you can do one of two thing:
138+
139+
1. Reload the app on each worklet code change. This virtually defeats the purpose of Fast Refresh. Not recommended.
140+
1. Patch `metro-runtime` package for it to send Fast Refresh updates to Worklet Runtimes. This is the recommended approach. **This patch does not require building React Native from source** You can find patching instructions in the [Worklets repository](https://github.com/software-mansion/react-native-reanimated/tree/main/packages/react-native-worklets/bundleMode/patches).
141+
142+
This patch is a temporary workaround until necessary changes are merged into Metro.
143+
144+
## Final steps
145+
146+
Make sure to clear your Metro bundler's cache to ensure that all the changes are applied correctly.
147+
148+
<Tabs groupId="package-managers">
149+
<TabItem value="npm" label="NPM">
150+
```bash
151+
npm start -- --reset-cache
152+
```
153+
</TabItem>
154+
155+
<TabItem value="yarn" label="YARN">
156+
```bash
157+
yarn start --reset-cache
158+
```
159+
</TabItem>
160+
</Tabs>
161+
162+
And that's it! You can now happily enjoy the Bundle Mode! You can learn more about using the Bundle Mode [here](/docs/bundleMode/usage).
163+
164+
## Reference
165+
166+
To see how the setup looks in a real project, you can check out the [Bundle Mode Showcase App](https://github.com/software-mansion-labs/Bundle-Mode-showcase-app) repository.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
sidebar_position: 3
3+
---
4+
5+
# Usage
6+
7+
## Running third party libraries in Worklets
8+
9+
Third party libraries have to be on an allow-list to use them in worklets. This is because libraries can come with side-effects that would break a Worklet Runtime. For instance, a library that imports something from React Native can't be used on a Worklet Runtime. This would load a second instance of React Native and break your app.
10+
11+
To add a library to the allow-list you only need to set the `workletizableModules` option in Worklets Babel plugin, which is an array of library names. For instance, if you want to use `my-library` on a Worklet Runtime.
12+
13+
```javascript
14+
/** @type {import('react-native-worklets/plugin').PluginOptions} */
15+
const workletsPluginOptions = {
16+
bundleMode: true,
17+
strictGlobal: true, // optional, but recommended
18+
// highlight-next-line
19+
workletizableModules: ['my-library'],
20+
};
21+
```
22+
23+
`workletizableModules` API is temporary and will be replaced with a more robust solution in the future.
24+
25+
## Running network requests in Worklets
26+
27+
In React Native ecosystem, new JavaScript runtimes don't come with networking capabilities out of the box. Worklets library provides a simplified version of `fetch` API that can be used on Worklet Runtimes - however, it might not be sufficient for all use cases.
28+
29+
For this reason, to enable `fetch` on Worklet Runtimes you have to toggle the `FETCH_PREVIEW_ENABLED` static feature flag in your app's `package.json`. You can find instructions on how to enable it [here](/docs/guides/feature-flags).
30+
31+
Running `fetch` also requires installing all the patches from the [Bundle Mode setup guide](/docs/bundleMode/setup).
32+
33+
:::note
34+
We are currently looking for third-party networking solutions that would provide same networking capabilities on Worklet Runtimes as what's available on the RN Runtime. We are open to adopting or integrating with such solutions. If you know about such solutions, please reach out to us on [GitHub](https://github.com/software-mansion/react-native-reanimated/issues).
35+
36+
:::
37+
38+
## Reference
39+
40+
To see how the setup looks in a real project, you can check out the [Bundle Mode Showcase App](https://github.com/software-mansion-labs/Bundle-Mode-showcase-app) repository.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"label": "Fundamentals",
3+
"position": 1,
4+
"link": {
5+
"type": "generated-index"
6+
}
7+
}

0 commit comments

Comments
 (0)