Summary:
In heap snapshots, it was found that really large (20 MB) strings representing network data
were being logged as part of `Systrace.beginEvent` strings from `MessageQueue` in DEV mode.
To combat this, use `JSON.stringify` with limits to keep the depth, strings, arrays, and objects
in check.
Changelog: [Internal] Change `stringifySafe` to have max limits on string size
Reviewed By: yungsters
Differential Revision: D20016501
fbshipit-source-id: e123016557bc154e4210e0b4df44360570da8016
Summary:
Removed an array.slice() call in the callImmediatesPass, which seems unnecessary to me, as the variable is immediately re-assigned on the next line.
Also fixed some flow issues, clarified a systrace marker and opensourced the relevant tests.
Changelog: [Internal] [Fixed] Improved JSTimer efficiency
Reviewed By: yungsters
Differential Revision: D20039181
fbshipit-source-id: 9b146980e8fa9f94b2f6153cc67cc7ced58104e5
Summary:
This diff replaces YellowBox with LogBox so that it can be deprecated and removed.
After this diff, it will no longer be possible to go back to YellowBox and all paths referencing it will be gone.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D19949695
fbshipit-source-id: 28a55866e514020bdcc6854aae565cffbbe8af58
Summary: changelog: [General] `console.error` calls, and uncaught exceptions are now displayed in the Metro logs as well
Reviewed By: passy
Differential Revision: D19743075
fbshipit-source-id: a665a06cfc7854ae785af177af8f2478bb1d76b0
Summary:
We currently use `BatchedBridge.registerCallableModule` to call JS from platform code in a bunch of places (e.g. `RCTDeviceEventEmitter.emit()`), including some pretty essential ones - for example, Networking relies on `RCTDeviceEventEmitter` to emit events to JS for network requests and errors. In order to make the migration to bridgeless mode as easy as possible, it'd be best if we didn't have to update all the callsites in JS and platform code, at least for core JS modules like `RCTDeviceEventEmitter`. So we'd like to implement this callable module pattern for bridgeless mode as well.
In this diff, I'm installing a global variable, `RN$registerCallableModule`, which will store the JS module name and factory function in C++. This can then be called from platform code (Java/Obj-C) to invoke a JS function on a module using the existing APIs (`context.getJSModule()` on Android, `enqueueJSCall()` or similar on iOS).
Changelog: [Internal]
Reviewed By: PeteTheHeat
Differential Revision: D18798852
fbshipit-source-id: fbe9eaecaf6f5cab5173beec999d3a933b13375d
Summary:
This diff adds a new `unstable_enableLogBox` function to opt-into the new LogBox experience. If LogBox is not enabled early enough, we show an error with instructions.
With this, LogBox can be enabled with:
```
require('react-native').unstable_enableLogBox();
```
Changelog: [General] [Adds] unstable_enableLogBox
Reviewed By: zackargyle, rubennorte
Differential Revision: D18808940
fbshipit-source-id: 4b0234ddc4d1646515bf63110d5b02133780512e
Summary:
This diff adds a new `unstable_enableLogBox` function to opt-into the new LogBox experience. If LogBox is not enabled early enough, we show an error with instructions.
With this, LogBox can be enabled with:
```
require('react-native').unstable_enableLogBox();
```
Changelog: [General] [Adds] unstable_enableLogBox
Reviewed By: zackargyle, rubennorte
Differential Revision: D18808940
fbshipit-source-id: 4b0234ddc4d1646515bf63110d5b02133780512e
Summary:
Right now we use `BatchedBridge.registerLazyCallableModule` for all JS modules except for `HMRClient`, which uses `registerCallableModule` instead (takes the module itself instead of a function that returns it). I'm standardizing on `registerLazyCallableModule` so that it will be easier to swap out the implementation later for bridgeless mode.
The only reason I could think why we wouldn't want to do this is if we're relying on some side effect of `require('HMRClient')` when setting up JS, but there don't seem to be any side effects in that module that I can see.
Changelog: [Internal]
Reviewed By: rickhanlonii
Differential Revision: D18798870
fbshipit-source-id: a5c950bdbfd998bb12e4843ee28ece08a26c84bf
Summary:
Fixes a bug where we were skewing some stack traces by sending 1-based column numbers to the Metro symbolication endpoint, which expects them to be 0-based. This is achieved by subtracting 1 from the column numbers we find in textual stack traces, which are almost universally 1-based in current JS engines.
The bug is only noticeable in *some* cases, namely where the column immediately following the correct one is in a different function.
NOTE: The behaviour under Hermes was fixed separately, in a previous commit. This fix applies to other engines (e.g. JSC).
Changelog: [General] [Fixed] - Fix stack traces showing the wrong function name in some cases
Reviewed By: cpojer
Differential Revision: D18628230
fbshipit-source-id: 5677803500e45a41c1005496d19c150526af2d07
Summary:
Makes stack trace parsing return a consistent representation of column numbers when using Hermes, whether we're executing bytecode (in prod) or source code (in dev). This is achieved by creating a new full-fidelity stack trace parser for Hermes.
NOTE: We still use the `stacktrace-parser` package for other engines, so this fix applies only to Hermes and not to JSC - that will be fixed separately in an upcoming diff.
This fixes a bug where we were skewing some stack traces by sending 1-based column numbers to the Metro symbolication endpoint, which expects them to be 0-based. The bug is only noticeable in *some* cases, namely where the column immediately following the correct one is in a different function.
Changelog: [Internal]
Reviewed By: cpojer
Differential Revision: D18627930
fbshipit-source-id: abd80846f00f24428670b2c92153564fb4bb2aff
Summary:
## Overview
This diff adds handling for syntax errors created using `buildCodeFrameError` which have a slightly different format than syntax errors thrown during transforms.
Changelog: [Internal]
Reviewed By: yungsters
Differential Revision: D18658502
fbshipit-source-id: 0836f2c16cdd57c10ed1e03dc7345d8e1ccf53f3
Summary:
We are rolling out exact-by-default syntax to xplat/js.
I had to manually move around some comments to preserve proper placement.
Changelog: [Internal]
Reviewed By: jbrown215
Differential Revision: D18633611
fbshipit-source-id: 48f7468dcc55b1d00985419d035a61c6820b3abe
Summary:
Removes the use of `parseErrorStack` in `_allocateCallback`, which was used to determine which timer API was allocating the callback (for Systrace purposes). Instead, we now use the already-existing `type` argument, which achieves the exact same thing but is much faster than parsing the stack trace.
Changelog: [General] [Fixed] - Reduce overhead of setting up timers in DEV
Reviewed By: yinghuitan
Differential Revision: D18233182
fbshipit-source-id: 190c0ffad8734cd889b790248e5a77cfb147454b
Summary:
The React team wants exceptions thrown during render to pop over the screen as fatals.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D18439258
fbshipit-source-id: dded7b9d93271c1a4eff682be521c7567dfe7d7e
Summary:
Changelog: [Internal]
Reverting the import to the previous local module style since importing from react-native seems to introduce some perf regression. We'll revisit this later in the future.
Reviewed By: yungsters
Differential Revision: D18383893
fbshipit-source-id: f11d46a4545768f39199fd6fd22fcf14905d0a74
Summary:
This diff changes the LogBox to show the code frame for the first non-collapsed stack frame. Let me know what you think about this change!
Changelog: [Internal] LogBox changes
Reviewed By: rickhanlonii
Differential Revision: D18372456
fbshipit-source-id: ddf6d6c53ab28d11d8355f4cb1cb071a00a7366e
Summary:
This diff adds error handling to logbox so that if there is an error either when parsing logs or when rendering LogBox, we show a native redbox with the error that was thrown and a message explaining that it's an internal React Native error.
Changelog: [Internal]
Reviewed By: cpojer
Differential Revision: D18394788
fbshipit-source-id: 5d74d58e4b28ef6d863079e83677fb23ef4ccb34
Summary:
still some generated files in www that need to land before we can release 0.111 here.
drop-conflicts
Changelog: [Internal]
(Note: this ignores all push blocking failures!)
Reviewed By: dsainati1
Differential Revision: D18278838
fbshipit-source-id: b20c3fefb3aab7c5fb614b33d846c7548184f49a
Summary:
Changelog: [Internal]
Moved the imports for `TurboModuleRegistry` and `TurboModule` from `react-native`. This was a jscodeshift with the script: P120688078
Reviewed By: yungsters
Differential Revision: D18262538
fbshipit-source-id: 48fac15229c897408928511c5ecbb42f17ec7b42
Summary:
Changelog: [Internal]
* The original intention was to export both `get()` and `getEnforcing()` from TurboModuleRegistry.js, so define export default there
* Exposes `TurboModule` type on the top-level `'react-native'` import
* Tried this out on `NativeSegmentFetcher`
Reviewed By: yungsters
Differential Revision: D18262535
fbshipit-source-id: a46f2b8b6147531998efac8aa3b8259885224902
Summary:
This diff adds handling for syntax errors.
## Strategy
To do this we introduce a new log level type syntax, giving us these levels with semantics:
- `warn` - console warns, show collapsed, dismissible
- `error` - console errors, show collapsed, dismissible
- `fatal` - thrown exceptions, show expanded, not dismissible
- `syntax` - thrown exceptions for invalid syntax, show expanded, not dismissible
Syntax errors shows expanded, covers all other errors, and are only dismissible when the syntax error is fixed and updated with Fast Refresh. Once the syntax error is fixed, it reveals any previously covered fatals, errors, or warnings behind it
In many ways, this makes syntax errors the highest level error.
## Visuals
Syntax errors also have their own display formatting. Stack traces for syntax errors don't make sense, so we don't show them. Instead, we show the syntax error message and a code frame for the error.
The code frame is also updated so that is doesn't wrap and is horizontally scrollable, making it easier to read.
## Detecting syntax errors
To detect syntax errors we've updated `LogBoxData.addException` to call the parse function `parseLogBoxException`. This method will perform a regex on the error message to detect:
- file name
- location
- error message
- codeframe
If this regex fails for any reason to find all four parts, we'll fall back to a fatal. Over time we'll update this regex to be more robust and handle more cases we've missed.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D18278862
fbshipit-source-id: 59069aba38a27c44787e5248b2973c3a345c4a0a
Summary:
This diff adds support for thrown exceptions to redboxes, and hides the native redbox when we show an error in LogBox.
Changelog: [Internal]
Reviewed By: cpojer
Differential Revision: D18212064
fbshipit-source-id: 92031d554968bcb079f81568673ae85697c8f5ad
Summary:
This diff switches the exception manager over to the reportException native module function on iOS and adds a new field `extraData.showRedbox` as a temporary hack to control hiding/showing native redboxes for LogBox.
Once LogBox is rolled out we'll remove this field, so we're hacking it into the available unused and untyped extraData bag, which will simplify gutting it in the future.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D18212047
fbshipit-source-id: f14e31d90359b7d455a73c2368ce010c28364a5c
Summary:
When testing out the NetworkOverlay, I noticed that we were creating a lot of WebSocket connections for localhost:8097. Rick found that this is because we're trying to connect to React devtools every 2 seconds: https://github.com/facebook/react/blob/master/packages/react-devtools-core/src/backend.js#L67 and it appears we create a new WebSocket every time.
Dan suggested that we use opening the dev menu as a trigger for attempting to connect to React devtools. This diff uses RCTNativeAppEventEmitter to emit an event from native when the dev menu/dialog is shown, and listening to that event in JS to attempt to connect to devtools.
I'm also making the change of passing in a websocket instead of just passing in the host + port; this way it will only attempt to connect once on each call to `connectToDevTools` (otherwise, we would attempt to reconnect every 2 seconds as soon as the dev menu is opened, and then the next time the menu is opened we'd so start that *again*, and so on - I could have it keep track of whether it's already connecting and avoid doing it again, but this is easier and should be sufficient, I think).
We should probably also update the suggested troubleshooting tips on the devtools page to reflect this change, so that people don't get confused.
Changelog: [General] [Fixed] Fix issue where we attempt to connect to React devtools every 2 seconds
Reviewed By: mmmulani
Differential Revision: D17919808
fbshipit-source-id: 4658d995c274574d22f2f54ea06d7f29ef2f54dc
Summary:
Renders frames in RedBox in a greyed-out style when their `collapse` field is set to `true`. This avoids outright hiding information in the stack trace while still drawing attention to frames that are likely to be more meaningful.
Changelog: [General] [Changed] - Render collapsed JavaScript frames in RedBox
Reviewed By: rickhanlonii
Differential Revision: D18039438
fbshipit-source-id: 527588f11c0bff495842be7036cd1293bab65eb9
Summary:
Removes support for the non-standard `framesToPop` error property from React Native. Redboxes will now ignore this field. The way to skip uninformative frames in stack traces going forward is to use Metro's `customizeFrame` config option, for which the React Native CLI ships useful defaults (see: https://github.com/react-native-community/cli/pull/596, https://github.com/react-native-community/cli/pull/780)
Changelog: [General] [Removed] - Remove support for framesToPop from ExceptionsManager
Reviewed By: rickhanlonii
Differential Revision: D17877444
fbshipit-source-id: 04aa332c45ad35a99ae20e05fb87b34c91a557ab
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/26883
This diff fixes an issue reported in https://github.com/facebook/react-native/issues/26788 where logs in the Chrome console were showing a different location than previous versions.
In the change here, we stop wrapping the console functions to attach the metro websocket in any environment that isn't a native app environment. We do this by checking `global.nativeLoggingHook` which is bound only by native apps and not environments like the Chrome DevTools.
Changelog: [General][Fixed] - Fix wrong lines logging in Chrome debugger
Reviewed By: cpojer, gaearon
Differential Revision: D17951707
fbshipit-source-id: f045ea9abaa8aecc6afb8eca7db9842146a3d872
Summary:
Replaces the use of `framesToPop` in `_allocateCallback` (in `__DEV__` only) with statically accessing the second frame of the stack.
Changelog: [Internal]
Reviewed By: cpojer
Differential Revision: D17877261
fbshipit-source-id: 8e4d0eb2ed7984b66a99752fb21f7909474fda8f
Summary: Report fast refreshes to the native module that handles reporting
Reviewed By: cpojer
Differential Revision: D17528523
fbshipit-source-id: 6f8a0b72a18c2d08ab160dc8b6621fce5420a473
Summary: This diff adds reload reasons to Fast Refresh. This will help us understand why, for internal Facebook users, Fast Refresh is bailing out to a full reload so that we can improve it for everyone.
Reviewed By: cpojer
Differential Revision: D17499348
fbshipit-source-id: b6e73dc3f396c8531a0872f5572a13928450bb3b
Summary: Reuse preprocessed exception message when sending the symbolicated update to the redbox, in case `preprocessException` has actually modified it.
Reviewed By: cpojer
Differential Revision: D17318008
fbshipit-source-id: 8b4c606c662140fb44c5305e2f3c7faa0b60f0ee
Summary:
Fix a simple error where `types[index]` was being accessed after it was cleared, instead of before.
## Changelog
[iOS] [Fixed] - never call deleteTimer for setImmediate and requestIdleCallback
Pull Request resolved: https://github.com/facebook/react-native/pull/26113
Test Plan: None
Differential Revision: D17314489
Pulled By: cpojer
fbshipit-source-id: 74715f0f7cc2d5cee3b97a67313c5e96e9d6c555
Summary:
Looks like we broke iOS redbox in D16812212. It stopped showing up because the feature detection stopped working, and we started calling noops. The fix is an explicit platform check.
Fixes#26260
Reviewed By: motiz88
Differential Revision: D17139310
fbshipit-source-id: 829eec23cbb49151ac250889c34ab28d36b05e6a
Summary:
This Diff is being posted for discussion purposes. It will not be ready to land until React DevTools v4 has been published to NPM.
Update React Native to be compatible with the [new version 4 React DevTools extension](https://github.com/bvaughn/react-devtools-experimental).
**Note that this is a breaking change**, as the version 3 and version 4 backends are **not compatible**. Once this update ships (in React Native) users will be required to update their version of the [`react-devtools` NPM package](https://www.npmjs.com/package/react-devtools). The same will be true for IDEs like Nuclide as well as other developer tools like Flipper and [React Native Debugger](https://github.com/jhen0409/react-native-debugger).
Related changes also included in this diff are:
* Pass an explicit whitelist of style props for the React Native style editor (to improve developer experience when adding new styles).
* Update `YellowBox` console patching to coordinate with DevTools own console patching.
* Also improved formatting slightly by not calling `stringifySafe` for strings (since this adds visible quotation marks).
Regarding the console patching- component stacks will be appended by default when there's no DevTools frontend open. The frontend will provide an option to turn this behavior off though:
{F168852162}
React DevTools will detect if the new version is used with an older version of React Native, and offer inline upgrade instructions:
{F169306863}
**Note that the change to the `RCTEnableTurboModule` will not be included in this Diff**. I've just turned those off temporarily so I can use v8+Chrome for debugging.
Reviewed By: rickhanlonii
Differential Revision: D15973709
fbshipit-source-id: bb9d83fc829af4693e7a10a622acc95a411a48e4
Summary: Adds a way for the app to add information to an exception report before it is sent to native. This API is not final.
Reviewed By: rubennorte
Differential Revision: D16984151
fbshipit-source-id: 8450356d608e05deaed437e2a35094cd16962027
Summary:
This diff adds a JS spec for RCTImageLoader, and conforms to it in ObjC++. Since RCTImageLoader isn't called from JS, the js spec is empty. Since `/CoreModules/` is the only dir in OSS which supports TM, move the ObjC++ impl there.
The change in `NativeExceptionsManager.js` fixes a weird bug I was hitting in codegen, where the codegen cpp file wouldn't compile due to unused variable.
Reviewed By: JoshuaGross
Differential Revision: D16495674
fbshipit-source-id: 191897b87730a6b0b96022eedc6412551fae04a6
Summary:
* Adds Flow types to `error-guard.js` and propagates them via the `ErrorUtils` module.
* Fixes some call sites to account for the stricter (correct) types.
Differential Revision: D16619538
fbshipit-source-id: c006ff2736ec380763956c4b89702cf44dd4deb0
Summary: `parseErrorStack` (which uses the `stacktrace-parser` package) can return null file names, line numbers and column numbers. This diff updates the associated types and adds explicit null checks in some call sites.
Reviewed By: rickhanlonii
Differential Revision: D16542176
fbshipit-source-id: b72c73c05b95df0bbcb5b5baa7bc2d42cff1e074
Summary:
# Context
In https://github.com/facebook/react/pull/16141 we imported `ReactFiberErrorDialog` unchanged from React. That implementation was not idempotent: if passed the same error instance multiple times, it would amend its `message` property every time, eventually leading to bloat and low-signal logs.
The message bloat problem is most evident when rendering multiple `lazy()` components that expose the same Error reference to React (e.g. due to some cache that vends the same rejected Promise multiple times).
More broadly, there's a need for structured, machine-readable logging to replace stringly-typed interfaces in both the production and development use cases.
# This diff
* We leave the user-supplied `message` field intact and instead do all the formatting inside `ExceptionsManager`. To avoid needless complexity, this **doesn't** always have the exact same output as the old code (but it does come close). See tests for the specifics.
* The only mutation we do on React-captured error instances is setting the `componentStack` expando property. This replaces any previously-captured component stack rather than adding to it, and so doesn't create bloat.
* We also report the exception fields `componentStack`, unformatted `message` (as `originalMessage`) and `name` directly to `NativeExceptionsManager` for future use.
Reviewed By: cpojer
Differential Revision: D16331228
fbshipit-source-id: 7b0539c2c83c7dd4e56db8508afcf367931ac71d
Summary:
This change switches the sending of log messages to Metro from HTTP over to WebSocket. This is what I should have done from the beginning *however* I only spent very little time on this initially, didn't realize that it would be a popular feature *and* we didn't have a persistent WebSocket connection on the client before that was always on. Together with D16442656 we can finally make this happen!
This change:
* Changes the `fetch` call to `HMRClient.log`
* Removes the middleware and integrates logging with `HmrServer` directly in Metro.
* Simplifies the logging logic as WebSockets guarantee messages are processed in order.
This also fixes an issue makovkastar identified when using the `MessageQueue` spy: because we send messages back and forth over the bridge, using `console.log` within `MessageQueue`'s spy method will actually cause an infinite logging loop. This is the proper solution to that problem instead of hacking around it using custom headers.
Note: in a follow-up we will rename these modules to drop the `HMR` prefix. We have not come up with a better name yet and are open to ideas.
Reviewed By: sebmck
Differential Revision: D16458499
fbshipit-source-id: 4c06acece1fef5234015c877354fb730b155168c
Summary:
This updates `react-refresh` to 0.3.0 which brings a new feature: we can now detect if the root fails on _the initial mount_. In that case we currently can't recover with Fast Refresh because we don't know which element to retry mounting. (In the future, we can lift this limitation, but it would require more changes in React renderer.)
Before this diff, after you fix an error on initial mount, you would see a blank screen (because nothing managed to mount).
After this diff, after you fix an error on initial mount, you would fall back to a full reload.
This diff doesn't affect errors on updates. We can recover from those, just like before.
Reviewed By: cpojer
Differential Revision: D16440836
fbshipit-source-id: 4a414202a9eab894acd7baa0525c25ff003dd323
Summary: Renames `ReactFiberErrorDialog-test` to `ExceptionsManager-test` and adds tests for `console.error` and exceptions not captured by React. Some of this functionality is covered by the RNTester integration tests, but this JS test suite is both more comprehensive and easier to iterate against.
Reviewed By: cpojer
Differential Revision: D16363166
fbshipit-source-id: 32a4b89bb50131fae86e3c03db7eacbbcf86966b
Summary:
https://github.com/facebook/react-native/pull/25671 added a shallow unit test for `ReactFiberErrorDialog`, mocking out the (JS) `ExceptionsManager` module. This rewrites that test in terms of `NativeExceptionsManager` instead, so the integration with `ExceptionsManager` is also tested.
Also adds tests for the behaviour of the `framesToPop` and `jsEngine` extended error fields, and for passing a frozen error object (seeing as we potentially mutate the error).
Reviewed By: rickhanlonii
Differential Revision: D16330341
fbshipit-source-id: 0b514d1c8f193a114748739ec31ddb4e06e4d2fd
Summary: I originally added `forceFullRefresh` as an escape hatch in case Fast Refresh is too unreliable. In practice we haven't seen any major issues with it. Since this option is already very obscure, I'm just removing it.
Reviewed By: shergin
Differential Revision: D16286632
fbshipit-source-id: c3dc44cffd459912e194e273acf868f3380c64cc
Summary: These warnings are both noisy and unactionable to product developers when you disconnect a Metro server. You also see them *after* the redbox is closed anyway, so you kind of already know if symbolication didn't work. So I'm downgrading it to a simple log.
Reviewed By: motiz88
Differential Revision: D16285591
fbshipit-source-id: c0e4c9168f66f4573404aa336ab889e4e9da0c22
Summary:
@public
`reportException` is a new method on `NativeExceptionsManager` that is designed to allow more structured and flexible JS error reporting. `reportFatalException` and `reportSoftException` are now deprecated.
In addition to all the usual exception fields, `reportException` also accepts an `extraData` property which the JS exception handler can populate with arbitrary JSON-serialisable data (here: the raw stack trace, the current JS engine, and the number of frames popped off the call stack by the exception handler). The contents of `extraData` get attached as JSON to the `JavascriptException` instance (or just logged, in the case of `console.error`).
This change is backwards compatible in two senses:
1. We have a JS fallback that uses `reportFatalException` and `reportSoftException` if the new native method is unavailable.
2. We have a Java fallback that implements `reportFatalException` and `reportSoftException` in terms of `reportException`.
Naturally, both fallbacks mentioned above discard `extraData`.
NOTE: The current implementation is Android-only; for the time being, iOS will continue to use the JS fallback.
While we're in `ExceptionsManager.js`, this also changes `dismissRedbox()` to be optional (which it is, since it's Android-only); existing call sites already guard it with a null check so this requires no other changes.
Reviewed By: mmmulani
Differential Revision: D16133080
fbshipit-source-id: d0b209d58da40b736df63155bbea232e94ce635c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/25671
Moves the RN-specific `ReactFiberErrorDialog` implementation from React to RN for easier iteration. Also adds new unit tests.
This current change is additive, so we're compatible with the current React renderer which still uses `ExceptionsManager` and not the file added here. After the corresponding React update we can remove `ExceptionsManager` from the RN private interface entirely.
Reviewed By: cpojer
Differential Revision: D16278938
fbshipit-source-id: 0c2c0c3e65e524e079730ae3b0cc23e0c0bdc5fd
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: 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 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:
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:
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:
This removes React Transform HMR in favor of the new React Refresh implementation. It should only affect the "Enable Hot Reloading" mode. In further diffs I will remove "React Transform HMR" completely.
This is technically a breaking change for Metro so it'll need a version bump.
Reviewed By: rickhanlonii, rubennorte
Differential Revision: D15903585
fbshipit-source-id: 074380b00868cb31857f599a03799d3584c35d87
Summary:
This adds the Fresh Babel plugin and runtime to React Native dependencies. **They're not actually being used or enabled yet**. This is purely additive and just gets the deps setup out of the way for future diffs.
The `react-refresh` source of truth is in the React repo.
Reviewed By: cpojer
Differential Revision: D15828330
fbshipit-source-id: 67ec2dea8c896477ff8b434445f1730e388ea67a
Summary: Developer tools have a lot of dependencies on the bridge, so for now I'm just disabling them in bridgeless mode entirely by guarding everything in `setUpDeveloperTools` with the `RN$Bridgeless` flag. Also consolidating some of the stuff Dan added to `InitializeCore` for hot reloading in here.
Reviewed By: zackargyle
Differential Revision: D15797924
fbshipit-source-id: 360ea81a2844e49f7281eed259fc16a541148ac2
Summary: For bridgeless RN we're not going to use the JSTimers module + Timing native module for timers (e.g. setTimeout, setImmediate, etc.). Instead we're going to install global functions from cpp for each of these, so we can just skip setUpTimers entirely in this case.
Reviewed By: fkgozali
Differential Revision: D15790638
fbshipit-source-id: 1626fe90a27cb8d385cbb700ad932969f708f0cb
Summary:
In bridgeless mode we don't want to set up the batched bridge, which is set up as part of InitializeCore. Instead of deleting InitializeCore completely, let's just skip this step if we're in bridgeless mode, which we'll detect using a global variable set on the runtime from cpp (`RN$Bridgeless`).
This way you still get an error if the bridge is somehow not set up properly when you're not in bridgeless mode (it won't fail silently).
Reviewed By: fkgozali
Differential Revision: D15721940
fbshipit-source-id: 73896e25874dd000f37d1abc9cf6be549ab3434f
Summary:
The original reason for vendoring the fetch polyfill was to remove the default blob response type but this was reverted.
Here's a little history around the fetch polyfill and the blob issue:
- Original commit introducing the vendored polyfill: #19333, the goal was to fix a memory leak because our blob implementation doesn't release resources automatically. Not an ideal fix but since the issue was pretty severe and the infra for a proper fix was not in place.
- This introduced an issue when downloading images using `fetch` which was fixed by #22063 which re-added the default blob content type. However that re-introduced the original fetch memory leak.
- We have better infra now with jsi and I was able to get blob deallocation working, see #24405
Currently the vendored fetch polyfill is useless since it was changed back to the original version. We can just use the npm version again. I also updated to 3.0 which brings better spec compliance and support for cancellation via `AbortController`, https://github.com/github/fetch/releases/tag/v3.0.0.
## Changelog
[General] [Changed] - Remove vendored fetch polyfill, update to whatwg-fetch@3.0
Pull Request resolved: https://github.com/facebook/react-native/pull/24418
Differential Revision: D14932683
Pulled By: cpojer
fbshipit-source-id: 915e3d25978e8b9d7507ed807e7fba45aa88385a
Summary:
This is the same diff as D14786123 but with one of the buck targets fixed that only failed on continuous and didn't run during land time.
This moves Map/Set to fb internal. We do not need them in open source any more but we still need this in some apps at FB that use an old version of JSC.
Reviewed By: rickhanlonii
Differential Revision: D15713305
fbshipit-source-id: caec43c76a6255b2af1693c13d8dea31d7d674f5
Summary:
Hot reloading propagates upwards through the inverse dependency tree — from a file you edited, to the files that import it, and so on. However, we can't always reevaluate everything. Many core infra modules can't run twice, and also the more you run, the more the risk of encountering a module with init side effects. So our practical compromise is to stop the propagation when we reach a module whose exports look like React components. We say that such module "accepts" an update. This means that in practice, changes trigger module reevaluation up to the closest component modules from the edited file. (If you edited a component file, it re-executes alone — unless it exports a non-component.)
However, current implementation has a problem. Sometimes there is an inverse dependency path that has no "accepting" modules whatsoever. For example, maybe you're editing some core module, and its inverse dependency tree reaches goes into React Native itself. Or maybe it reaches the entry point with a bunch of side effects that can't be repeated, like registering the app root component.
In the past, such cases would lead to confusing errors like "Expected `FBPrelude.conclude()` to have been called" after hot reload. This was because we kept re-executing modules all the way upwards, even if there is nothing that can accept the update on the path. Eventually we'd reach top-level modules in the import graph that don't like to run twice.
This diff changes the logic so that we *don't attempt* to re-execute the module factories if we know that some inverse dependency path doesn't terminate in a component. In that case we know we simply *can't apply the hot update* because it doesn't stop at a point we can handle, like a React component.
Since the hot update fails in this case, I'm making it fall back to a regular reload. This is similar to how webpack handles a similar situation on the web. This means that hot updates normally don't refresh, but if we can't apply a hot update to this file, we do refresh automatically.
Reviewed By: cpojer
Differential Revision: D15631864
fbshipit-source-id: 52cd1b03739fd760f1b1b1ab8c7276a150cc3c4c
Summary: This moves Map/Set to fb internal. We do not need them in open source any more but we still need this in some apps at FB that use an old version of JSC.
Reviewed By: TheSavior
Differential Revision: D14786123
fbshipit-source-id: 1c49b47d547ad30f2d93c00b44382cf410100b67
Summary: When metro is not running, D15559151 caused infinite exceptions (fetch threw an error if it couldn't connect to localhost:8081) which affected UI. Swallow those errors and everything works well, with or without metro.
Reviewed By: yungsters
Differential Revision: D15588623
fbshipit-source-id: d170ea82478545836a7a22a228196c9778e93ef0
Summary:
The original reason for vendoring the fetch polyfill was to remove the default blob response type but this was reverted.
Here's a little history around the fetch polyfill and the blob issue:
- Original commit introducing the vendored polyfill: #19333, the goal was to fix a memory leak because our blob implementation doesn't release resources automatically. Not an ideal fix but since the issue was pretty severe and the infra for a proper fix was not in place.
- This introduced an issue when downloading images using `fetch` which was fixed by #22063 which re-added the default blob content type. However that re-introduced the original fetch memory leak.
- We have better infra now with jsi and I was able to get blob deallocation working, see #24405
Currently the vendored fetch polyfill is useless since it was changed back to the original version. We can just use the npm version again. I also updated to 3.0 which brings better spec compliance and support for cancellation via `AbortController`, https://github.com/github/fetch/releases/tag/v3.0.0.
## Changelog
[General] [Changed] - Remove vendored fetch polyfill, update to whatwg-fetch@3.0
Pull Request resolved: https://github.com/facebook/react-native/pull/24418
Differential Revision: D14932683
Pulled By: cpojer
fbshipit-source-id: 915e3d25978e8b9d7507ed807e7fba45aa88385a
Summary:
People ask "How do you use `console.log` with React Native?" and there is no good answer. This diff aims to stop people from asking this question.
See https://fb.workplace.com/groups/rn.core/permalink/2372327062999018/ for context.
This logging relies on network requests which can cause logs to show up out-of-order. To reduce the likelihood I queue every log message on the server for a maximum of 200ms. There could be other methods, like using websocket, but that seems more complex than is necessary at least in the beginning.
I considered various throttling strategies because this could be quite chatty and possibly problematic, however I think we can just ship this and iterate based on feedback. On my very underpowered laptop I logged a random number every 10 milliseconds and it didn't cause any issues or slowdown.
Reviewed By: gaearon
Differential Revision: D15559151
fbshipit-source-id: 552001622af0937ae3a37d2bd8c1b96e7ca52020
Summary:
This is another step in moving RN towards standard path-based requires, updating more code to use path-based requires. See the umbrella issue at https://github.com/facebook/react-native/issues/24316 for more detail.
## Changelog
[General] [Changed] - Replace more Haste imports with path-based imports
Pull Request resolved: https://github.com/facebook/react-native/pull/25001
Differential Revision: D15467829
Pulled By: cpojer
fbshipit-source-id: 58c364bb4c1c757689907d5ed0d0f3fac0e22f3f