Skip to content

Commit dc8a103

Browse files
committed
Allow RCTBundleURLProvider to request an inline source map (#37878)
Summary: See: http://blog.nparashuram.com/2019/10/debugging-react-native-ios-apps-with.html When using direct debugging with JavaScriptCore, Safari Web Inspector doesn't pick up the source map over the network. Instead, as far as I can tell, it expects you to pass the source URL at the time you load your bundle: https://developer.apple.com/documentation/javascriptcore/jscontext/1451384-evaluatescript?language=objc . This leads to a very sub-par developer experience debugging the JSbundle directly. It will however, pick up an inline source map. Therefore, let's add a way to have React Native tell metro to request an inline source map. I did this by modifying `RCTBundleURLProvider` to have a new query parameter for `inlineSourceMap`, and set to true by default for JSC. [IOS] [ADDED] - Added support to inline the source map via RCTBundleURLProvider Pull Request resolved: #37878 Test Plan: I can put a breakpoint in RNTester, via Safari Web Inspector, in human readable code :D <img width="1728" alt="Screenshot 2023-06-14 at 4 09 03 AM" src="https://github.com/facebook/react-native/assets/6722175/055277fa-d887-4566-9dc6-3ea07a1a60b0"> Reviewed By: motiz88 Differential Revision: D46855418 Pulled By: huntie fbshipit-source-id: 2134cdbcd0a3e81052d26ed75f83601ae4ddecfe
1 parent ff27568 commit dc8a103

File tree

3 files changed

+115
-21
lines changed

3 files changed

+115
-21
lines changed

Diff for: packages/react-native/React/Base/RCTBundleURLProvider.h

+33-2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ RCT_EXTERN void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed);
101101

102102
@property (nonatomic, assign) BOOL enableMinification;
103103
@property (nonatomic, assign) BOOL enableDev;
104+
@property (nonatomic, assign) BOOL inlineSourceMap;
104105

105106
/**
106107
* The scheme/protocol used of the packager, the default is the http protocol
@@ -125,13 +126,32 @@ RCT_EXTERN void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed);
125126
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
126127
packagerHost:(NSString *)packagerHost
127128
enableDev:(BOOL)enableDev
128-
enableMinification:(BOOL)enableMinification;
129+
enableMinification:(BOOL)enableMinification
130+
__deprecated_msg(
131+
"Use `jsBundleURLForBundleRoot:packagerHost:enableDev:enableMinification:inlineSourceMap:` instead");
132+
133+
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
134+
packagerHost:(NSString *)packagerHost
135+
packagerScheme:(NSString *)scheme
136+
enableDev:(BOOL)enableDev
137+
enableMinification:(BOOL)enableMinification
138+
modulesOnly:(BOOL)modulesOnly
139+
runModule:(BOOL)runModule
140+
__deprecated_msg(
141+
"Use jsBundleURLForBundleRoot:packagerHost:enableDev:enableMinification:inlineSourceMap:modulesOnly:runModule:` instead");
142+
143+
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
144+
packagerHost:(NSString *)packagerHost
145+
enableDev:(BOOL)enableDev
146+
enableMinification:(BOOL)enableMinification
147+
inlineSourceMap:(BOOL)inlineSourceMap;
129148

130149
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
131150
packagerHost:(NSString *)packagerHost
132151
packagerScheme:(NSString *)scheme
133152
enableDev:(BOOL)enableDev
134153
enableMinification:(BOOL)enableMinification
154+
inlineSourceMap:(BOOL)inlineSourceMap
135155
modulesOnly:(BOOL)modulesOnly
136156
runModule:(BOOL)runModule;
137157
/**
@@ -142,6 +162,17 @@ RCT_EXTERN void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed);
142162
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
143163
packagerHost:(NSString *)packagerHost
144164
scheme:(NSString *)scheme
145-
query:(NSString *)query;
165+
query:(NSString *)query
166+
__deprecated_msg("Use version with queryItems parameter instead");
167+
168+
/**
169+
* Given a hostname for the packager and a resource path (including "/"), return the URL to the resource.
170+
* In general, please use the instance method to decide if the packager is running and fallback to the pre-packaged
171+
* resource if it is not: -resourceURLForResourceRoot:resourceName:resourceExtension:offlineBundle:
172+
*/
173+
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
174+
packagerHost:(NSString *)packagerHost
175+
scheme:(NSString *)scheme
176+
queryItems:(NSArray<NSURLQueryItem *> *)queryItems;
146177

147178
@end

Diff for: packages/react-native/React/Base/RCTBundleURLProvider.mm

+78-15
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed)
2222
kRCTAllowPackagerAccess = allowed;
2323
}
2424
#endif
25+
static NSString *const kRCTPlatformName = @"ios";
2526
static NSString *const kRCTPackagerSchemeKey = @"RCT_packager_scheme";
2627
static NSString *const kRCTJsLocationKey = @"RCT_jsLocation";
2728
static NSString *const kRCTEnableDevKey = @"RCT_enableDev";
2829
static NSString *const kRCTEnableMinificationKey = @"RCT_enableMinification";
30+
static NSString *const kRCTInlineSourceMapKey = @"RCT_inlineSourceMap";
2931

3032
@implementation RCTBundleURLProvider
3133

@@ -187,6 +189,7 @@ - (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackURLProvider:(
187189
packagerScheme:[self packagerScheme]
188190
enableDev:[self enableDev]
189191
enableMinification:[self enableMinification]
192+
inlineSourceMap:[self inlineSourceMap]
190193
modulesOnly:NO
191194
runModule:YES];
192195
}
@@ -199,6 +202,7 @@ - (NSURL *)jsBundleURLForSplitBundleRoot:(NSString *)bundleRoot
199202
packagerScheme:[self packagerScheme]
200203
enableDev:[self enableDev]
201204
enableMinification:[self enableMinification]
205+
inlineSourceMap:[self inlineSourceMap]
202206
modulesOnly:YES
203207
runModule:NO];
204208
}
@@ -238,20 +242,37 @@ - (NSURL *)resourceURLForResourceRoot:(NSString *)root
238242
return [[self class] resourceURLForResourcePath:path
239243
packagerHost:packagerServerHostPort
240244
scheme:packagerServerScheme
241-
query:nil];
245+
queryItems:nil];
242246
}
243247

244248
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
245249
packagerHost:(NSString *)packagerHost
246250
enableDev:(BOOL)enableDev
247251
enableMinification:(BOOL)enableMinification
252+
{
253+
return [self jsBundleURLForBundleRoot:bundleRoot
254+
packagerHost:packagerHost
255+
packagerScheme:nil
256+
enableDev:enableDev
257+
enableMinification:enableMinification
258+
inlineSourceMap:NO
259+
modulesOnly:NO
260+
runModule:YES];
261+
}
262+
263+
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
264+
packagerHost:(NSString *)packagerHost
265+
enableDev:(BOOL)enableDev
266+
enableMinification:(BOOL)enableMinification
267+
inlineSourceMap:(BOOL)inlineSourceMap
248268

249269
{
250270
return [self jsBundleURLForBundleRoot:bundleRoot
251271
packagerHost:packagerHost
252272
packagerScheme:nil
253273
enableDev:enableDev
254274
enableMinification:enableMinification
275+
inlineSourceMap:inlineSourceMap
255276
modulesOnly:NO
256277
runModule:YES];
257278
}
@@ -263,27 +284,45 @@ + (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
263284
enableMinification:(BOOL)enableMinification
264285
modulesOnly:(BOOL)modulesOnly
265286
runModule:(BOOL)runModule
287+
{
288+
return [self jsBundleURLForBundleRoot:bundleRoot
289+
packagerHost:packagerHost
290+
packagerScheme:nil
291+
enableDev:enableDev
292+
enableMinification:enableMinification
293+
inlineSourceMap:NO
294+
modulesOnly:modulesOnly
295+
runModule:runModule];
296+
}
297+
298+
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
299+
packagerHost:(NSString *)packagerHost
300+
packagerScheme:(NSString *)scheme
301+
enableDev:(BOOL)enableDev
302+
enableMinification:(BOOL)enableMinification
303+
inlineSourceMap:(BOOL)inlineSourceMap
304+
modulesOnly:(BOOL)modulesOnly
305+
runModule:(BOOL)runModule
266306
{
267307
NSString *path = [NSString stringWithFormat:@"/%@.bundle", bundleRoot];
308+
BOOL lazy = enableDev;
309+
NSArray<NSURLQueryItem *> *queryItems = @[
310+
[[NSURLQueryItem alloc] initWithName:@"platform" value:kRCTPlatformName],
311+
[[NSURLQueryItem alloc] initWithName:@"dev" value:enableDev ? @"true" : @"false"],
312+
[[NSURLQueryItem alloc] initWithName:@"minify" value:enableMinification ? @"true" : @"false"],
313+
[[NSURLQueryItem alloc] initWithName:@"inlineSourceMap" value:inlineSourceMap ? @"true" : @"false"],
314+
[[NSURLQueryItem alloc] initWithName:@"modulesOnly" value:modulesOnly ? @"true" : @"false"],
315+
[[NSURLQueryItem alloc] initWithName:@"runModule" value:runModule ? @"true" : @"false"],
268316
#ifdef HERMES_BYTECODE_VERSION
269-
NSString *runtimeBytecodeVersion = [NSString stringWithFormat:@"&runtimeBytecodeVersion=%u", HERMES_BYTECODE_VERSION];
270-
#else
271-
NSString *runtimeBytecodeVersion = @"";
272-
#endif
273-
274-
// When we support only iOS 8 and above, use queryItems for a better API.
275-
NSString *query = [NSString stringWithFormat:@"platform=ios&dev=%@&minify=%@&modulesOnly=%@&runModule=%@%@",
276-
enableDev ? @"true" : @"false",
277-
enableMinification ? @"true" : @"false",
278-
modulesOnly ? @"true" : @"false",
279-
runModule ? @"true" : @"false",
280-
runtimeBytecodeVersion];
317+
[[NSURLQueryItem alloc] initWithName:@"runtimeBytecodeVersion" value:HERMES_BYTECODE_VERSION],
318+
#endif
319+
];
281320

282321
NSString *bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleIdentifierKey];
283322
if (bundleID) {
284-
query = [NSString stringWithFormat:@"%@&app=%@", query, bundleID];
323+
queryItems = [queryItems arrayByAddingObject:[[NSURLQueryItem alloc] initWithName:@"app" value:bundleID]];
285324
}
286-
return [[self class] resourceURLForResourcePath:path packagerHost:packagerHost scheme:scheme query:query];
325+
return [[self class] resourceURLForResourcePath:path packagerHost:packagerHost scheme:scheme queryItems:queryItems];
287326
}
288327

289328
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
@@ -300,6 +339,20 @@ + (NSURL *)resourceURLForResourcePath:(NSString *)path
300339
return components.URL;
301340
}
302341

342+
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
343+
packagerHost:(NSString *)packagerHost
344+
scheme:(NSString *)scheme
345+
queryItems:(NSArray<NSURLQueryItem *> *)queryItems
346+
{
347+
NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHostPort(packagerHost, scheme)
348+
resolvingAgainstBaseURL:NO];
349+
components.path = path;
350+
if (queryItems != nil) {
351+
components.queryItems = queryItems;
352+
}
353+
return components.URL;
354+
}
355+
303356
- (void)updateValue:(id)object forKey:(NSString *)key
304357
{
305358
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
@@ -317,6 +370,11 @@ - (BOOL)enableMinification
317370
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableMinificationKey];
318371
}
319372

373+
- (BOOL)inlineSourceMap
374+
{
375+
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTInlineSourceMapKey];
376+
}
377+
320378
- (NSString *)jsLocation
321379
{
322380
return [[NSUserDefaults standardUserDefaults] stringForKey:kRCTJsLocationKey];
@@ -346,6 +404,11 @@ - (void)setEnableMinification:(BOOL)enableMinification
346404
[self updateValue:@(enableMinification) forKey:kRCTEnableMinificationKey];
347405
}
348406

407+
- (void)setInlineSourceMap:(BOOL)inlineSourceMap
408+
{
409+
[self updateValue:@(inlineSourceMap) forKey:kRCTInlineSourceMapKey];
410+
}
411+
349412
- (void)setPackagerScheme:(NSString *)packagerScheme
350413
{
351414
[self updateValue:packagerScheme forKey:kRCTPackagerSchemeKey];

Diff for: packages/rn-tester/RNTesterUnitTests/RCTBundleURLProviderTests.m

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
URLWithString:
2828
[NSString
2929
stringWithFormat:
30-
@"http://localhost:8081/%@.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&runtimeBytecodeVersion=%u&app=com.apple.dt.xctest.tool",
30+
@"http://localhost:8081/%@.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&runtimeBytecodeVersion=%u&app=com.apple.dt.xctest.tool",
3131
testFile,
3232
HERMES_BYTECODE_VERSION]];
3333
#else
3434
return [NSURL
3535
URLWithString:
3636
[NSString
3737
stringWithFormat:
38-
@"http://localhost:8081/%@.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.apple.dt.xctest.tool",
38+
@"http://localhost:8081/%@.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.apple.dt.xctest.tool",
3939
testFile]];
4040
#endif
4141
}
@@ -47,15 +47,15 @@
4747
URLWithString:
4848
[NSString
4949
stringWithFormat:
50-
@"http://192.168.1.1:8081/%@.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&runtimeBytecodeVersion=%u&app=com.apple.dt.xctest.tool",
50+
@"http://192.168.1.1:8081/%@.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&runtimeBytecodeVersion=%u&app=com.apple.dt.xctest.tool",
5151
testFile,
5252
HERMES_BYTECODE_VERSION]];
5353
#else
5454
return [NSURL
5555
URLWithString:
5656
[NSString
5757
stringWithFormat:
58-
@"http://192.168.1.1:8081/%@.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.apple.dt.xctest.tool",
58+
@"http://192.168.1.1:8081/%@.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.apple.dt.xctest.tool",
5959
testFile]];
6060
#endif
6161
}

0 commit comments

Comments
 (0)