Skip to content

Commit 2995b01

Browse files
thymikeeokwasniewski
authored andcommitted
Create custom resolver and utils package for out-of-tree platforms (#32)
* rename react-native package to @callstack/react-native-visionos * wip: metro setup for other platform * fix(flow): add .ios.visionos as support platform * fix some flow errors * fix flow * revert Platform.select change * revert KeyboardAvoidingView change * fix type * change kBundlePath to ios.visionos * fix: remove redundant isVisionOS * use custom resolver options to read platform for OOT * fix types * remove formatting * add/remove platform checks * document variant behavior * use visionOS Keyboard mock * use visionOS KeyboardAvoidingView mock * use visionOS InputAccessoryView mock * test: add test for metroPlatformResolver * move implementation to user space * create out-of-tree-platforms package and bring back resolver options * revert flow changes * revert sourceExts changes * update links * add comments * fix visionos typo * adjust lockfile * revert loadMetroConfig change * remove podfile lock * revert scripts changes
1 parent cdb73c3 commit 2995b01

File tree

7 files changed

+102
-0
lines changed

7 files changed

+102
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# @callstack/out-of-tree-platforms
2+
3+
[![Version][version-badge]][package]
4+
5+
Utilities for Out of Tree (OOT) platforms.
6+
7+
## `getPlatformResolver`
8+
9+
```js
10+
getPlatformResolver(options: ResolverConfig): CustomResolver
11+
```
12+
13+
### options
14+
15+
```js
16+
type ResolverConfig = {
17+
platformImplementations: {[platform: string]: string},
18+
};
19+
```
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
* @format
9+
*/
10+
11+
import type {CustomResolver} from 'metro-resolver';
12+
13+
type ResolverConfig = {
14+
platformNameMap: {[platform: string]: string},
15+
};
16+
17+
/**
18+
* Creates a custom Metro resolver that maps platform extensions to package names.
19+
* To be used in app's `metro.config.js` as `resolver.resolveRequest`.
20+
*/
21+
const getPlatformResolver = (config: ResolverConfig): CustomResolver => {
22+
return (context, moduleName, platform) => {
23+
// `customResolverOptions` is populated through `?resolver.platformExtension` query params
24+
// in the jsBundleURLForBundleRoot method of the react-native/React/Base/RCTBundleURLProvider.mm
25+
const platformExtension = context.customResolverOptions?.platformExtension;
26+
let modifiedModuleName = moduleName;
27+
28+
if (
29+
typeof platformExtension === 'string' &&
30+
config.platformNameMap?.[platformExtension]
31+
) {
32+
const packageName = config.platformNameMap[platformExtension];
33+
if (moduleName === 'react-native') {
34+
modifiedModuleName = packageName;
35+
} else if (moduleName.startsWith('react-native/')) {
36+
modifiedModuleName = `${packageName}/${modifiedModuleName.slice(
37+
'react-native/'.length,
38+
)}`;
39+
}
40+
}
41+
42+
return context.resolveRequest(context, modifiedModuleName, platform);
43+
};
44+
};
45+
46+
module.exports = {getPlatformResolver};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "@callstack/out-of-tree-platforms",
3+
"version": "0.74.0",
4+
"description": "Utils for React Native out of tree platforms.",
5+
"license": "MIT",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/callstack/react-native-visionos.git",
9+
"directory": "packages/out-of-tree-platforms"
10+
},
11+
"homepage": "https://github.com/callstack/react-native-visionos/tree/HEAD/packages/out-of-tree-platforms#readme",
12+
"keywords": [
13+
"out-of-tree",
14+
"react-native"
15+
],
16+
"bugs": "https://github.com/facebook/react-native/issues",
17+
"engines": {
18+
"node": ">=18"
19+
},
20+
"exports": "./index.js",
21+
"devDependencies": {
22+
"metro-resolver": "^0.80.0"
23+
}
24+
}

packages/react-native/React/Base/RCTBundleURLProvider.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ + (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
274274
BOOL lazy = enableDev;
275275
NSArray<NSURLQueryItem *> *queryItems = @[
276276
[[NSURLQueryItem alloc] initWithName:@"platform" value:RCTPlatformName],
277+
#if TARGET_OS_VISION
278+
[[NSURLQueryItem alloc] initWithName:@"resolver.platformExtension" value:RCTPlatformExtension],
279+
#endif
277280
[[NSURLQueryItem alloc] initWithName:@"dev" value:enableDev ? @"true" : @"false"],
278281
[[NSURLQueryItem alloc] initWithName:@"lazy" value:lazy ? @"true" : @"false"],
279282
[[NSURLQueryItem alloc] initWithName:@"minify" value:enableMinification ? @"true" : @"false"],

packages/react-native/React/Base/RCTConstants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#import <React/RCTDefines.h>
99

1010
RCT_EXTERN NSString *const RCTPlatformName;
11+
#if TARGET_OS_VISION
12+
RCT_EXTERN NSString *const RCTPlatformExtension;
13+
#endif
1114

1215
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
1316
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;

packages/react-native/React/Base/RCTConstants.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#import "RCTConstants.h"
99

1010
NSString *const RCTPlatformName = @"ios";
11+
#if TARGET_OS_VISION
12+
NSString *const RCTPlatformExtension = @"visionos";
13+
#endif
1114

1215
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
1316
NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey = @"traitCollection";

packages/rn-tester/metro.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
'use strict';
1111

12+
const {getPlatformResolver} = require('@callstack/out-of-tree-platforms');
1213
const {getDefaultConfig} = require('@react-native/metro-config');
1314
const {mergeConfig} = require('metro-config');
1415
const path = require('path');
@@ -36,6 +37,9 @@ const config = {
3637
extraNodeModules: {
3738
'react-native': path.resolve(__dirname, '../react-native'),
3839
},
40+
resolveRequest: getPlatformResolver({
41+
platformNameMap: [{visionos: '@callstack/react-native-visionos'}],
42+
}),
3943
},
4044
};
4145

0 commit comments

Comments
 (0)