Summary:
returning type of Bubbling and Direct Event should be always void of Promise (if async). Other situations shouldn't be permitted.
Reformated all cases when it the function wasn't void.
Reviewed By: rickhanlonii
Differential Revision: D16165962
fbshipit-source-id: 7c1377c3ed4bd54a431a13e5bcda4f7ec0adf4dc
Summary:
I'd like to use `Modal`’s flow types in my application to make a reusable component.
## Changelog
[JavaScript] [Added] - Exported `Modal`’s types
Pull Request resolved: https://github.com/facebook/react-native/pull/25554
Test Plan: n/a
Differential Revision: D16180231
Pulled By: cpojer
fbshipit-source-id: 9cfd5163a187954783102bfe4d9b4d1dbc8c6e6d
Summary: It's pointless to handle non optional key if value has withDefaul so I'm adding a rule into parser preventing from such cases
Reviewed By: lunaleaps
Differential Revision: D16166709
fbshipit-source-id: 38cef522b217917a3a4886d857720932f2ebb475
Summary: This diff changes a few things around so that a diff coming on top of this stack will be smaller. The aim of this change is to add a method `registerEntryPoint` which will allow a client to subscribe to updates for multiple bundles.
Reviewed By: gaearon
Differential Revision: D16131963
fbshipit-source-id: d460d6647b15a711021c7a3a51f52486a1aea535
Summary:
Running a PROD JS bundle with a DEV binary used to redbox with Fast Refresh on. The error said "HMRClient is not a registered callable module".
This isn't a new issue: https://www.google.com/search?q=%22hmrclient%20is%20not%20a%20registered%22. However, now it happens every time because `setup()` is now called unconditionally in a DEV native build.
Because a combination of DEV binary + PROD JS is technically possible, I'm adding a tiny shim that will make it a no-op instead of crashing. It will also explain what's wrong if you *intentionally* try to turn on Fast Refresh.
Reviewed By: sahrens
Differential Revision: D16145378
fbshipit-source-id: 0b9c0a6f30c02ca7f4a0133048450bdde3576ad2
Summary: These files are generated by tool, not for manual edit. So let this marker tell IDEs so.
Reviewed By: hramos, cpojer
Differential Revision: D16097171
fbshipit-source-id: 1f98a4d4e21acca0a7fbd386ff174dd9197c2129
Summary:
This PR adds initial support for Project Catalyst a.k.a. UIKitForMac. This is not yet meant for production, but this is enough for RNTester to successfully compile and mostly work :)
Some APIs are not supported on the Mac -- e.g. telephony, and deprecated APIs are removed on Mac ���-- those had to be ifdef'd out via platform checks.
The biggest limitation right now is that I couldn't get Web Socket code to successfully compile, and so there are a lot of temporary platform checks for that , and the RCTWebSocket.xcodeproj is marked as not supporting UIKitForMac. Again -- temporary, until someone with more knowledge knows how to fix this.
https://github.com/react-native-community/discussions-and-proposals/issues/131
## Changelog
[iOS] [Added] - Fixed compilation for macOS (Project Catalyst) -- not meant for production use yet
Pull Request resolved: https://github.com/facebook/react-native/pull/25427
Test Plan:
- Open RNTester/RNTester.xcodeproj with Xcode 10.2, run it like a normal iOS app -- make sure it compiles and runs correctly (no regression)
- Open the same project with Xcode 11 beta 2 (or higher) on macOS Catalina beta, select "My Mac" as device target, and run -- see that it actually compiles and runs. **Note** there are unfortunately some required steps:
- change build configuration to Release (because packager doesn't work correctly yet)
- change development team to yours if Xcode tells you to
- go to RNTester project → Build phases → Link binary with libraries, and change `platforms` for `libRCTWebSocket.a` to `iOS` (without Mac compatibility). I can't commit that change because it breaks compatibility with earlier Xcode versions
The two extra steps for successful compile will disappear once web socket compilation for Catalyst is fixed
Reviewed By: mmmulani
Differential Revision: D16088263
Pulled By: sammy-SC
fbshipit-source-id: 9c0b932b048e50a8e0f336eaa0612851b1909cae
Summary: There is a `setUpDeveloperTools.js` and a `setupDevtools.js` files. While they do set up different devtools it is very confusing to have these two files. This diff inlines one in the other which should bring more clarity.
Reviewed By: gaearon
Differential Revision: D16121236
fbshipit-source-id: 45641c7af9639ede6dc237ac53b763cd804a05c2
Summary:
This adds a few more methods that are forwarded to Metro, most notably `console.group`, `console.groupCollapsed` and `console.groupEnd`. When using `console.group`, node.js's `console` implementation will use indentation for log messages. `console.groupCollapsed`, for now, will simply not print anything to the console. This removes all of the Relay information that was impossible to look at in Metro before.
In the future, I'd like to consider somehow including collapsed groups in the output with a way to interact and navigate through them but for now, if people would like to debug Relay queries, they should use whatever they have been using before Metro had logs.
Reviewed By: gaearon
Differential Revision: D16108266
fbshipit-source-id: 97337d93eed0b8cb464df78b59ade1fe340b7f6f
Summary:
This simplifies the first log message for every single reload. Here are the changes:
* I dropped the "application" word because at Facebook we consider these views "surfaces". However, the method is explicitly called "runApplication" because in open source most people will only have a single "application". Removing the word and instead relying on the user specified string avoids the naming problem and doesn't take away from the information.
* I removed the `__DEV__` and performance optimization log. The way RN is set up, developers will always have the correct settings for these in either dev or prod and printing them every time is superfluous. Also, it had a typo. How is it possible nobody ever noticed this?
* I also simplified the invariant below to be half as long. I think it still has the same amount of information with fewer words (this is shown in a RedBox where there isn't that much space)
Reviewed By: rubennorte
Differential Revision: D16108248
fbshipit-source-id: 57351c68fa855c02bfbb1db6416d8db61eab4c19
Summary: Visible property isn't used by native modal, neither in iOS nor in Android
Reviewed By: osdnk
Differential Revision: D16107927
fbshipit-source-id: 6f8b8db11abc0942f5af3abcc0245bc066da8c6b
Summary: D16107933 disabled the logs around setup unless they are explicitly enabled and this diff disables all logs from this module entirely unless they are explicitly turned on at the top of the file.
Reviewed By: gaearon
Differential Revision: D16108151
fbshipit-source-id: 355aaf8624fb0778884f25f02d58fe4e1237d686
Summary: This module logs helpful messages in `__DEV__` but it only logs actionable performance logs when the flag on top of the file is enabled. This diff changes those to only log when the toggle on top of the file is enabled as well.
Reviewed By: gaearon
Differential Revision: D16107933
fbshipit-source-id: 7671bc521af984d617a0f5ffc0eacd1aa5674a62
Summary:
Using Ricky's last changes I managed to subscribe for both new and old event name.
Fixed event to proper one for codegen in native code.
Reviewed By: TheSavior
Differential Revision: D16065660
fbshipit-source-id: b5d3762d673a34bbdf5a8e60ff4d51617c8adb81
Summary:
`WithDefault` appears not to be required to be prefixed with `?` because it's option value per se.
Fixed tests, removed `?` where needed, updated snapshots and review them. Added mechanism fro throwing error when `?WithDefault` found. Add tests for it.
Reviewed By: rubennorte
Differential Revision: D16048463
fbshipit-source-id: f55ed7454aacf0b8c42944a9b5c1037ad1b360fe
Summary: This defines various sub specs to support building TurboModules that implement the codegen'ed specs.
Reviewed By: PeteTheHeat
Differential Revision: D16043221
fbshipit-source-id: 27ed532be929c11c8fe648632da8a72061cbc8b0
Summary:
This PR adds support for custom `StickyHeaderComponent` to be used in ScrollView (and by extension in FlatList, SectionList..).
Motivation: I've been working on a FlatList with hidable header that has a search field in it. Something like https://medium.com/appandflow/react-native-collapsible-navbar-e51a049b560a but using a FlatList w/ pull-to-refresh. The implementation can be found at https://snack.expo.io/vonovak/hidable-header-flatlist .
I used the `ListHeaderComponent` prop to render the custom header - as opposed to absolute positioning which is used in the linked article because I also need the loading indicator (I added `refreshing` and `onRefresh` for that) to show up above the header.
I proceeded by adding `stickyHeaderIndices={[0]}` to keep the header at the top, which seems to be the idiomatic way to do so. Then I added `Animated.View` with custom translation logic to the rendered header.
All appears to be working fine at the first sight - when you tap any item, you'll see it react to touch (red underlay). You'll also see the header becomes hidden if I scroll far enough and appears again after scrolling up. BUT - when you scroll down so that the header becomes hidden and tap the first visible item in the list, it will not react to touches! The reason is that `ScrollViewStickyHeader`
https://github.com/facebook/react-native/blob/9a84970c35d22b68fb3d8eac019c7f415a14c888/Libraries/Components/ScrollView/ScrollView.js#L984
has its own translation logic and when I tap onto the item at the top of the list, it seems like I'm tapping the item but I'm in fact tapping that `ScrollViewStickyHeader`.
I tried working around this by not specifying `stickyHeaderIndices={[0]}` and using `ListHeaderComponentStyle` prop (this needed some additional changes in https://github.com/facebook/react-native/blob/9a84970c35d22b68fb3d8eac019c7f415a14c888/Libraries/Lists/VirtualizedList.js#L786, and the animation is junky for some reason - as if the header always needed to "catch up" with the scroll offset, causing jitter) and `CellRendererComponent` (junky animations too), but concluded that allowing to specify custom `StickyHeaderComponent` is the cleanest way to make something like this work. I'm slightly surprised I needed to do all this to make such a usual pattern work - am I missing something?
## Changelog
[GENERAL] [ADDED] - allow custom StickyHeader in ScrollView-based components
Pull Request resolved: https://github.com/facebook/react-native/pull/25428
Test Plan: This is a minor change that should not break anything; tested locally.
Differential Revision: D16073016
Pulled By: cpojer
fbshipit-source-id: cdb878d12a426068dbaa9a54367c1190a6c55328
Summary:
See https://fb.workplace.com/permalink.php?story_fbid=2337018256625463&id=100009037038038&substory_index=58 for motivation.
I opted for using a substring that is unlikely to come up in warnings in product code but is shared across all lean core warnings. I think this is good enough and won't require updates every time we deprecate a new module.
Reviewed By: yungsters
Differential Revision: D16073431
fbshipit-source-id: 136b9e8ab53c85d2de5ed7844780f5d082087a7d
Summary:
It's not needed to keep required providing default values even if they are not actually relevant.
Here I add a support for `null`, `0` of `false` instead by default and remove throwing errors if no other default value provided.
Reviewed By: rubennorte
Differential Revision: D16049047
fbshipit-source-id: bc4961af3873190568f2753fc4ec975354896df5
Summary:
It appears that `(e: BubblingEvent<T>) = mixed` exists only in given context and it's pointless to keep in this way. It could be simplified to `BubblingEventHandler<T>` without any negative consequences and that's the motivation of this diff.
The only tradeoff of this decision is leaving an opportunity to declare Bubbling/Direct event in the top of the file bc then analysing the code becomes much more difficult. However, it's not used anywhere so it's not a problem now and probably any time.
Also, changes the names to `DirectEventHandler` and `BubblingEventHandler` which are more related to current state. The names were updated in many places in code.
Reviewed By: rubennorte
Differential Revision: D16054571
fbshipit-source-id: 741d075eb46b80bac8eb73a6b30fc0b448cb3902
Summary:
This breaks virtualization, viewability callbacks, and other features, so should be warned against.
Hopefully this would have made D15890785 trivial to figure out.
Reviewed By: PeteTheHeat
Differential Revision: D16040939
fbshipit-source-id: 593cd5da9891450fdcb501aef41455cf2d7baa4f
Summary:
This diff adds a way for the codegen to handle view configs with non-standard top event names by adding a `paperTopLevelNameDeprecated` field to events in the schema.
## The problem
The problem this is solving is that Android host components build their own options for event settings in the view config. So instead of enforcing `onChange` to use the top level event name `topChange` like iOS does, Android can use `change` or `forbarChange` or anything the person adding the component wanted at the time:
```
// Expected
topChange: {
registrationName: 'onChange',
},
// Android
bringBackStargateYouCowards: {
registrationName: 'onChange',
},
```
This is possible because of the way Android builds these settings
```
// On iOS, notice that there's no option to change the top level name:
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTDirectEventBlock);
// On Android, you provide the top level event name
Override
public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.of(
"bringBackStargateYouCowards",
MapBuilder.of("registrationName", "onChange"));
}
```
Since the codegen does not allow us to specify the top level event name (similar to iOS), we don't have a way to customize the names to support android
## The solution
To fix this, we're adding an extra option the event flow types:
```
onBubblingChange: (event: BubblingEvent<Event, 'customBubblingName'>) => void,
onDirectChange: (event: DirectEvent<Event, 'customDirectName'>) => void,
```
These will register **both** top level names in the view config:
```
{
directEventTypes: {
// Notice the same registration name is configured for different top level events
topChange: {
registrationName: 'onChange',
},
bringBackStargateYouCowards: {
registrationName: 'onChange',
},
}
}
```
This means when either `topChange` or `bringBackStargateYouCowards` fires it will call the onChange listener. **This gives us the flexibility to rename the native event name without breaking backwards compatibility.** Old apps will work when `bringBackStargateYouCowards` is fired, and new apps with an update will work when `topChange` fires.
Note: only the correct name will be generated for Fabric so technically we don't even really need to migrate the paper names and this prop can be deleted when paper is gone.
Reviewed By: cpojer
Differential Revision: D16042065
fbshipit-source-id: 40d076b43ffbbfc6c65c3c19de481d922a2add62
Summary:
Depending on the style props of an Animated.View it may be optimised away
by the NativeViewHierarchyOptimizer, which will make the animation to
fail, because the native view is virtual (it does not exists
in the native view hierarchy).
Although the createAnimatedComponent already sets the collapsable property
based on the this._propsAnimated.__isNative flag, it won't work on all
cases, since the __isNative flag is only set when one starts the animation.
Which won't cause a re-render to occuor, thus not setting the collapsable
property to false.
In order to prevent this issue the HOC will just set the collapsable property
to false.
## Changelog
[Javascript] [Fixed] - Properly set collapsable to false before starting a nativeDriver animation
Pull Request resolved: https://github.com/facebook/react-native/pull/25361
Test Plan:
### **Without this patch:**
Run the following App on an Android device without this patch and click start.
Outcome: The animation **will not** make the text invisible.
### **With this patch:**
Run the following App on an Android device with this patch and click start.
Outcome: The animation **will** make the text invisible.
```javascript
import React, { Component, ReactNode } from 'react';
import { View, Text, TouchableOpacity, Animated, StyleSheet, Easing } from 'react-native';
interface Props { }
const Constants = {
animation: {
duration: 500,
},
};
const text =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed orci erat. Suspendisse feugiat elit gravida elit consequat ultrices. Sed sollicitudin ullamcorper molestie. Mauris a diam neque. Vivamus in lectus.';
class App extends Component<Props> {
anim: any;
constructor(props: Props) {
super(props);
this.anim = new Animated.Value(0);
}
handleStartPress = () => {
this.anim.setValue(0);
console.log('start');
Animated.timing(this.anim, {
duration: Constants.animation.duration,
toValue: 1,
easing: Easing.linear(),
useNativeDriver: true,
}).start();
};
render(): ReactNode {
return (
<View style={styles.container}>
<Animated.View
style={{
opacity: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}>
<Text>{text}</Text>
</Animated.View>
<TouchableOpacity
style={styles.startButton}
onPress={this.handleStartPress}>
<Text style={styles.startButtonText}>START</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: 'white',
flex: 1,
},
description: {
marginTop: 20,
paddingHorizontal: 10,
},
startButton: {
alignItems: 'center',
aspectRatio: 1,
backgroundColor: 'yellow',
borderRadius: 100,
height: 50,
justifyContent: 'center',
},
startButtonText: {
fontSize: 10,
fontWeight: 'bold',
},
});
export default App;
```
Closes https://github.com/facebook/react-native/issues/25318
Differential Revision: D15983822
Pulled By: cpojer
fbshipit-source-id: 1d790fbddc3103a2e34e114db956fa1fb465c1c9
Summary:
This is a revamp of how we decide whether to stop at a refresh boundary or to bubble to the next one.
We used to decide that at module initialization. However, that's both unnecessary overhead on start (for modules you don't plan to edit), and is actually insufficient.
In particular, even if a module only exports components (and thus is a Refresh Boundary), consecutive versions of that module might not be compatible.
For example, any of these changes should trigger reevaluation of parents:
- Adding or removing exports
- Renaming the exported component (which probably means you exported a different one, and we shouldn't preserve state)
- Converting from a class to a function, or back
- Wrapping something in a HOC
The new system handles these cases by comparing the Refresh "families" corresponding to exports, and bubbling the update up if some of them don't match up.
The tests have been rewritten from the webpack-inspired `module.hot` API (which we no longer use directly) to the Refresh API.
Reviewed By: rubennorte
Differential Revision: D16036044
fbshipit-source-id: 18018548d4aaa05877ae6fbaffe40c993c77cdf0
Summary: These files are no longer needed since all files codegen'd use flow types as the source 🎉
Reviewed By: cpojer
Differential Revision: D15961378
fbshipit-source-id: 510a298b2e97cd78a9a3648cbaa239e8134daa75
Summary:
Metro symbolication can be expensive in large apps. However, there is no need to symbolicate _runtime stacks from compile errors_. Those are pretty much useless anyway.
This will reduce the workload on Metro workers, and the delays when iterating with Fast Refresh, as the server will be busy much less often.
So I'm special-casing them and not sending the symbolication request anymore.
Reviewed By: rickhanlonii
Differential Revision: D16030087
fbshipit-source-id: 41f83ac01780c0a60cca777014e4ed95c0f3d14b
Summary:
On `textContentType` `newPassword` on ios, there is another property called `passwordRules` on ios 12 that can give hints to the os to generate a password with specific requirements like [here](https://developer.apple.com/password-rules/).
This is useful for apps that have a "register" screen with `emailAddress`/`username` and a `newPassword` fields, to let ios make a password that will satisfy the requirements and not one that might be not accepted after the user presses "register".
## Changelog
[iOS] [Added] - PasswordRules for new password textContentType input fields
Pull Request resolved: https://github.com/facebook/react-native/pull/25407
Test Plan: This is a bit harder, but to test you need to make an app that has associated domains with an apple-app-site-association file on that domain, enable iCloud Keychain on the test device, and then iOS will suggest a password, otherwise you will just get a warning on Xcode saying "Couldn't suggest password because of: blabla".
Differential Revision: D16028684
Pulled By: cpojer
fbshipit-source-id: d22426e07f1db45d1f79f5dad81f1465a9701f0b
Summary:
`TimePickerAndroid` has been merged With `DatePickerIOS` and `DatePickerAndroid` as part of Lean Core. See [repo](https://github.com/react-native-community/react-native-datetimepicker)
## Changelog
[General] [Deprecate] - Warning for `TimePickerAndroid`
Pull Request resolved: https://github.com/facebook/react-native/pull/25409
Test Plan: Warning prints when user imports `TimePickerAndroid`
Differential Revision: D16028676
Pulled By: cpojer
fbshipit-source-id: 5dfdb6d7cc144f7a171892ebd1f6b6b9b6334b56
Summary: The method 'viewIsDescendantOf' is not used in JS, to prevent future usages of this method we just remove it.
Reviewed By: JoshuaGross
Differential Revision: D16014666
fbshipit-source-id: da623a455df04851ce286427fb54849e4e9e720a
Summary: For consistency, we use the files checked in to github.
Reviewed By: JoshuaGross
Differential Revision: D15993128
fbshipit-source-id: 1e9fdd6b4111284c84cbd5a63d384ef481659b01
Summary:
Cleans up the implementation of `AndroidPicker` and the Flow types for the native components to almost work with `codegenNativeComponent`.
The remaining blocker is that the `items` prop is an array of objects: https://fburl.com/km8uj8x2
Reviewed By: rickhanlonii
Differential Revision: D15805611
fbshipit-source-id: 34bea83db8dbaaf6eb23b00e73e0c7ce292e8a32
Summary:
Note: iOS only.
This spec file (.h/.mm) was generated via FB internal codegen tool for TurboModule. The tool itself is not yet ready to be opensourced, but at least the generated file is. The output is based on all the Flow types added via https://github.com/facebook/react-native/issues/24875.
This file can be used by each ObjC NativeModule to be TurboModule compliant.
Reviewed By: rickhanlonii
Differential Revision: D15978911
fbshipit-source-id: 9e97495287bc406e0ed0ccf89cf370753b538772
Summary: This util is used for TurboModule codegen system - it's not used anywhere else for now.
Reviewed By: JoshuaGross
Differential Revision: D15971956
fbshipit-source-id: 3cb1c3df7fa96fd51d420abff1fbfd07b18fdae6
Summary:
We should remove all usages of React's legacy context API because it'll be removed from React at some point, it prevents some performance optimizations in updates and can cause conflicts between different context providers (like mixins).
This creates a new Context for `rootTag` (this granularity is intentional) so users that are consuming it via the legacy context API can start migrating away from it.
I didn't create a more generic context (like ReactRootContext, ReactApplicationContext) because having a more granular context makes it easier to track and remove it if we want to, and prevents re-rendering when users only care about certain values.
Reviewed By: rickhanlonii, cpojer
Differential Revision: D14941918
fbshipit-source-id: 7ceea62727d10a591367b7ed7c447309b286758d
Summary:
`DatePickerIOS` and `DatePickerAndroid` have been merged as part of Lean Core. See [repo](https://github.com/react-native-community/react-native-datetimepicker)
## Changelog
[General] [Deprecate] - Warning for `DatePickerIOS` and `DatePickerAndroid`
Pull Request resolved: https://github.com/facebook/react-native/pull/25374
Test Plan: Warning prints when user imports `DatePickerIOS` or `DatePickerAndroid`
Differential Revision: D15983829
Pulled By: cpojer
fbshipit-source-id: dfa35e204bb133a1b8de67c25abaa4338b956901
Summary: The schema for these view commands is lifted wholesale from the schema for TurboModules: P67239314
Reviewed By: rickhanlonii
Differential Revision: D15943109
fbshipit-source-id: a0ccd4e47067b62970218df6a32527c15868c4a5
Summary: If you make a syntax error while there is a redbox while Fast Refresh is on, we should dismiss that redbox. Otherwise there is no way for you to tell why your code is not working.
Reviewed By: rickhanlonii
Differential Revision: D15970337
fbshipit-source-id: 1ca6c9a1b2269d198ae726d3b64e5c51506503db
Summary: This updates the renderer and Fresh packages to pull in the new error handling behavior. The new feature is that roots that errored on last save get remounted after an edit. This allows much faster iteration in the Fast Refresh mode as you don't need to do a full reload after typos.
Reviewed By: bvaughn
Differential Revision: D15967396
fbshipit-source-id: 96a82e6a4e00a8cb636d7bca037a1a43552a4cd2
Summary:
If the error doesn't come in direct response to a user action, I think a redbox is too severe. I think we don't want to associate turning on Fast Refresh with a higher frequency of redboxes. So this downgrades these messages to warnings.
If you manually try to turn it off and on again, we'll still show a redbox to remind why it's not working.
Reviewed By: rickhanlonii, cpojer
Differential Revision: D15958952
fbshipit-source-id: bd144c98e87a9836871391ac583c268dca8009b3
Summary:
We have too many options in the Dev Menu, and they're really hard to pick from. They're also somewhat conflicting. This replaces two menu choices that have a similar purpose (faster iteration cycle) with one.
"Fast Refresh" tries to only update the affected modules, but falls back to doing a full reload if the update can't be handled by the React components.
If for some reason you prefer the "Reload-on-Save" behavior, please:
- Reach out to me so I can learn more about your use case.
- As a workaround, you can add `if (__DEV__) require.Refresh.forceFullRefresh = true` to your app's entry point to always do a full refresh.
Also note that I only removed the user-facing part of "Reload-on-Save". So if you have automation depending on it, that's gonna keep working.
I moved it above Systrace since it's a more generic feature.
As a total aside nit, I renamed "Enable Inspector" and "Disable Inspector" to "Show Inspector" and "Hide Inspector" because... that's what those options do, really.
Reviewed By: rickhanlonii
Differential Revision: D15958697
fbshipit-source-id: 20e856d56f661fe4d39b5ab47d8c44754bf70f67
Summary: The onRefresh event is a DirectEvent not a BubblingEvent
Reviewed By: PeteTheHeat
Differential Revision: D15969475
fbshipit-source-id: 049a6ffc74306246e8dbc3acdce5b0b26e849fc7
Summary:
Since we always create `module.hot` objects, the `module.hot` checks were unnecessary. They give a false impression that we're checking for a Hot Reloading mode. However, they're just Flow refinements and always exist in DEV. I made that explicit by throwing early.
Similarly, I removed a `module.hot` check inside `setupReactRefresh`, as it is always truish in DEV.
Finally, I'm adding a new mechanism as an escape hatch. It lets you do:
```
if (__DEV__) {
require.Refresh.forceFullRefresh = true;
}
```
in your entry point and opt into full refreshes on every edit. This sounds similar to "Reload-on-Save". That is because in the next diff, I plan to remove "Reload-on-Save" from user-visible options (but it'll stay for automated workflows).
So this workaround is intended for people who for one reason or another don't want to opt into Hot Reloading as an alternative. We'll need to talk to them and find out why.
Reviewed By: rickhanlonii
Differential Revision: D15958475
fbshipit-source-id: 674187ddf86a4e286dfae28f4182555a8b5d7396
Summary:
As we saw in D15947985, and later traced down to D5623623, the `hot` option isn't used by Metro anymore. The relevant transforms _always_ run in DEV regardless of the option.
Given that, it doesn't make sense that enabling or disabling Hot Reloading forces a full refresh. This significantly raises the usage barrier because **currently, you might have to wait ~20 seconds (on a large app) to just start using Hot Reloading when you're already in the middle of some screen.** So you just end up not using it.
This diff changes enabling/disabling Hot Reloading to be _instant_.
Here's how it works:
1. Now we always send the necessary info to the client via the new `HMRClient.setup()` function. It creates a Metro HMR client instance, but only actually sets up the socket if Hot Reloading is on.
2. The "Enable Hot Reloading" menu no longer forces a reload. Instead, it calls `HMRClient.enable()` which lazily sets up a socket (at most once).
3. The "Disable Hot Reloading" menu also doesn't trigger a refresh now. Instead, it calls `HMRClient.disable()`. We don't actually tear down the socket here because it's a pain to deal with race conditions and such. Instead, we keep the connection — but we _ignore the updates_ that come in while we're disabled.
4. As a result, it is possible to enable and disable it many times during a single session. (Updates while disabled would be ignored — which has a risk of making your running app inconsistent — but I'd argue it's expected and is worth it. You can always save a particular file to force it to update once the mode is on.)
5. In order to support "ignoring" updates, Metro's `HMRClient` (not to be confused with RN's module) now supports a `shouldApplyUpdates` field. The RN module uses it to disable handling updates when the mode is off.
6. In case there is an error that makes hot reloading unavailable (such as the server disconnecting), we surface the error only if the mode is on. If the mode is off, we stash the error message in the `_hmrUnavailableReason` variable, and display it next time you try to enable Hot Reloading.
Reviewed By: rickhanlonii
Differential Revision: D15958160
fbshipit-source-id: 8256fc4d5c2c3f653a78edf13b8515a5671953e4