Skip to content

Instantly share code, notes, and snippets.

@asklar
Last active April 8, 2021 00:05
Show Gist options
  • Save asklar/12069510eb609f5575b9471b70f495d2 to your computer and use it in GitHub Desktop.
Save asklar/12069510eb609f5575b9471b70f495d2 to your computer and use it in GitHub Desktop.
Folly usage in React Native and React Native for Windows

Limiting RN dependencies

Usage in React Native Windows

Today React Native Windows depends on RN core, which uses Folly and a number of other libraries (double-conversion, glog, sys).

Some [parts] of these libraries don’t work in UWP context (e.g. calling CreateFile on arbitrary paths).

We don’t build all of Folly, instead we carve out the minimum set of files that we need (and work in UWP).

Every time we take a new drop of Folly, we are opened up to new dependencies of Folly being introduced (e.g. double-conversion, fmt). These are dependencies of Folly but not used by RN or RNW. However, they are needed to build Folly.

The new dependencies might have conflicting licenses (e.g. the fmt library has an MIT license for the code, but some other non-MIT license for its docs).

Current solutions involve one of:

  • Fork a folly file. This makes ingesting new versions of folly more cumbersome. See folly forked files
  • Add stubs of the new dependencies, see stubs
  • PRs to folly to make some dependencies opt-in. Ideally we want to minimize having to fix up upstream folly and instead have RN core rely on a subset of folly that is stable and doesn't change much.

Example of a Folly PR to minimize unnecessary dependencies: facebook/folly#1551

Usage in Hermes (Windows)

folly::future is needed for Hermes inspector

Original attempt relied on an older version of folly that didn't use futures New attempt reimplemented a lot of the futures logic, but it became too big/complex. PR: microsoft/react-native-windows#7322

PR description

Our original work to enable Hermes inspector required downgrading Folly to an older version to make folly::future work on Windows. It is not practical to downgrade the Folly sources due to various genuine reasons.

The folly::future implementation in the current Folly source enable waiting on a future without blocking the thread using fibers, and it assumes that the thread is based on libevent loop. It is not practical for our threads to be driven by libevent for various reasons. Hence, we can't make the future implementation in the current folly source work in RNW trivially (without bringing a huge amount of new dependencies, such as libevent, boost threading library etc.).

We tried various more elegant approaches compared to this change unsucessfully.

In this change, we are including a minimal implementation of folly::future extracted from Folly source. The implementation included only 5 header and these headers
are overriding the headers from current folly source by being included ahead of folly sources. The changes we made in folly::future are based on following assumptions,

  1. We don't need fiber backed implementation as we don't want to wait on a future in our use cases, but we only want continuation into an executor.
  2. Waiting on a future requires bringing a few more dependencies and stubbing. We've avoid it by stubbing our wait implemenatatino. It is currently ok as our use cases don't wait on a future.
  3. All priority, duration based APIs are not needed, as we don't have a use case.

One core assumption to legitimize this change is that adding any more dependency on folly::future will be flagged in future. Folly source is not basically UWP-aware or UWP-friendly.

(Anandraj/Vlad/Nick to add more details if needed)

Questions

  • Can RN carve out its own sub-set of Folly that is dependency-stable
  • Do we still need Folly long term? folly::dynamic can be replaced with jsi, so maybe the only thing we need is the JSON parsing/toString logic?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment