Skip to content

Commit c167ffb

Browse files
feat(docs): Add Expo modules guide (#2671)
## Summary: Add guide explaining how to integrate Expo modules in a react-native-macos project ## Test Plan: Run docs locally <img width="1158" height="840" alt="image" src="https://github.com/user-attachments/assets/fdd2663e-d304-4230-a63b-48fb82896449" />
1 parent d30f249 commit c167ffb

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
---
2+
title: Install Expo modules
3+
sidebar_position: 2
4+
---
5+
6+
:::info
7+
macOS support for Expo modules is currently experimental.
8+
:::
9+
10+
To use Expo modules in your app, you will need to install and configure the `expo` package.
11+
12+
The `expo` package has a small footprint; it includes only a minimal set of packages that are needed in nearly every app and the module and autolinking infrastructure that other Expo SDK packages are built with. Once the `expo` package is installed and configured in your project, you can use `npx expo install` to add any other Expo module from the SDK.
13+
14+
The following instructions apply to installing the latest version of Expo modules. For previous versions, check the
15+
Expo docs for compatibility for which [Expo SDK version depends on a React Native version](https://docs.expo.dev/versions/latest/#each-expo-sdk-version-depends-on-a-react-native-version).
16+
17+
```shell
18+
npm install expo
19+
```
20+
21+
Once installation is complete, apply the changes from the following diffs to configure Expo modules in your project. This is expected to take about five minutes, and you may need to adapt it slightly depending on how customized your project is.
22+
23+
24+
### Configuration for macOS
25+
26+
To configure your macOS project to use Expo modules, you'll need to make changes to the `Podfile` and your `AppDelegate`.
27+
28+
Start by modifying your `Podfile` to use the `use_expo_modules!` directive. This will enable autolinking for Expo modules in your project.
29+
30+
```diff macos/Podfile
31+
+require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
32+
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
33+
34+
target 'myapp' do
35+
- config = use_native_modules!
36+
+ use_expo_modules!
37+
+
38+
+ config_command = [
39+
+ 'npx',
40+
+ 'expo-modules-autolinking',
41+
+ 'react-native-config',
42+
+ '--json',
43+
+ '--platform',
44+
+ 'ios'
45+
+ ]
46+
+ config = use_native_modules!(config_command)
47+
48+
use_react_native!(
49+
- :path => '../node_modules/react-native-macos',
50+
+ :path => "#{config[:reactNativePath]}-macos",
51+
```
52+
53+
Optionally, you can also add additional delegate methods to your **AppDelegate.swift**. Some libraries may require them, so unless you have a good reason to leave them out, it is recommended to add them. [See delegate methods in AppDelegate.swift](https://github.com/expo/expo/blob/sdk-53/templates/expo-template-bare-minimum/ios/HelloWorld/AppDelegate.swift#L24-L42).
54+
55+
The last step is to install the project's CocoaPods again to pull in Expo modules that are detected by `use_expo_modules!` directive that we added to the **Podfile**:
56+
57+
```shell
58+
# Install pods
59+
npx pod-install
60+
```
61+
62+
### Configure Expo CLI for bundling on macOS
63+
64+
We recommend using Expo CLI and related tooling configurations to bundle your app JavaScript code and assets. This adds support for using the `"main"` field in **package.json**. Not using Expo CLI for bundling may result in unexpected behavior. [Learn more about Expo CLI](https://docs.expo.dev/bare/using-expo-cli/).
65+
66+
#### Use babel-preset-expo in your babel.config.js
67+
```diff babel.config.js
68+
- presets: ['module:@react-native/babel-preset'],
69+
+ presets: ['babel-preset-expo'],
70+
```
71+
72+
#### Extend expo/metro-config in your metro.config.js
73+
74+
```diff metro.config.js
75+
-const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
76+
+const { getDefaultConfig } = require('expo/metro-config');
77+
+const { mergeConfig } = require('@react-native/metro-config');
78+
79+
/**
80+
* Metro configuration
81+
```
82+
83+
#### Configure macOS project to bundle with Expo CLI
84+
85+
Replace the shell script under **Build Phases** > **Bundle React Native code and images** in Xcode with the following:
86+
87+
```sh /bin/sh
88+
if [[ -f "$PODS_ROOT/../.xcode.env" ]]; then
89+
source "$PODS_ROOT/../.xcode.env"
90+
fi
91+
if [[ -f "$PODS_ROOT/../.xcode.env.local" ]]; then
92+
source "$PODS_ROOT/../.xcode.env.local"
93+
fi
94+
95+
# The project root by default is one level up from the ios directory
96+
export PROJECT_ROOT="$PROJECT_DIR"/..
97+
98+
if [[ "$CONFIGURATION" = *Debug* ]]; then
99+
export SKIP_BUNDLING=1
100+
fi
101+
if [[ -z "$ENTRY_FILE" ]]; then
102+
# Set the entry JS file using the bundler's entry resolution.
103+
export ENTRY_FILE="$("$NODE_BINARY" -e "require('expo/scripts/resolveAppEntry')" "$PROJECT_ROOT" ios relative | tail -n 1)"
104+
fi
105+
106+
if [[ -z "$CLI_PATH" ]]; then
107+
# Use Expo CLI
108+
export CLI_PATH="$("$NODE_BINARY" --print "require.resolve('@expo/cli')")"
109+
fi
110+
if [[ -z "$BUNDLE_COMMAND" ]]; then
111+
# Default Expo CLI command for bundling
112+
export BUNDLE_COMMAND="export:embed"
113+
fi
114+
115+
`"$NODE_BINARY" --print "require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'"`
116+
```
117+
118+
And add support the `"main"` field in **package.json** by making the following change to **AppDelegate.swift**:
119+
120+
```diff AppDelegate.swift
121+
override func bundleURL() -> URL? {
122+
#if DEBUG
123+
- RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
124+
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
125+
#else
126+
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
127+
#endif
128+
```
129+
130+
131+
## Usage
132+
133+
### Verifying installation
134+
135+
You can verify that the installation was successful by logging a value from [`expo-constants`](https://docs.expo.dev/versions/latest/sdk/constants).
136+
137+
- Run `npx expo install expo-constants`
138+
- Then, run `npx expo run` and modify your app JavaScript code to add the following:
139+
140+
```js
141+
import Constants from 'expo-constants';
142+
console.log(Constants.systemFonts);
143+
```
144+
145+
### Using Expo SDK packages
146+
147+
Once the `expo` package is installed and configured in your project, you can use `npx expo install` to add any other Expo module from the SDK. See [Using Expo Libraries](https://docs.expo.dev/workflow/using-libraries/) for more information.
148+
149+
### Expo modules included in the `expo` package
150+
151+
The following Expo modules are brought in as dependencies of the `expo` package:
152+
153+
- [`expo-asset`](https://docs.expo.dev/versions/latest/sdk/asset) - A JavaScript-only package that builds around `expo-file-system` and provides a common foundation for assets across all Expo modules.
154+
- [`expo-constants`](https://docs.expo.dev/versions/latest/sdk/constants) - Provides access to the manifest.
155+
- [`expo-file-system`](https://docs.expo.dev/versions/latest/sdk/filesystem) - Interact with the device file system. Used by `expo-asset` and many other Expo modules. Commonly used directly by developers in application code.
156+
- [`expo-font`](https://docs.expo.dev/versions/latest/sdk/font) - Load fonts at runtime. This module is optional and can be safely removed, however; it is recommended if you use `expo-dev-client` for development and it is required by `@expo/vector-icons`.
157+
- [`expo-keep-awake`](https://docs.expo.dev/versions/latest/sdk/keep-awake) - Prevents your device from going to sleep while developing your app. This module is optional and can be safely removed.
158+
159+
To exclude any of these modules, refer to the following guide on [excluding modules from autolinking](#excluding-specific-modules-from-autolinking).
160+
161+
### Excluding specific modules from autolinking
162+
163+
If you need to exclude native code from Expo modules you are not using, but were installed by other dependencies, you can use the [`expo.autolinking.exclude`](https://docs.expo.dev/modules/autolinking/#exclude) property in **package.json**:
164+
165+
```json package.json
166+
{
167+
"name": "...",
168+
"dependencies": {},
169+
"expo": {
170+
"autolinking": {
171+
"exclude": ["expo-keep-awake"]
172+
}
173+
}
174+
}
175+
```

0 commit comments

Comments
 (0)