facebook / react-strict-dom

React Strict DOM (RSD) standardizes the development of styled React components for web and native.
https://facebook.github.io/react-strict-dom
MIT License
3.16k stars 160 forks source link

Eject expo example #157

Open necolas opened 4 months ago

necolas commented 4 months ago

Describe the feature request

Expo has a number of issues and it is preventing us from testing as accurately as I'd like. Fixing these issues is not a priority for Expo. We should look into ejecting, forking, patching, de-frameworking, or other ways to work around these problems preventing Expo from working with xplat React.

  1. ~Issues upgrading. Each time I try to upgrade the SDK there are new issues. Most recently I can't upgrade to Expo 51 because Expo packages are now missing dependencies and haven't been tested to work in npm monorepos~
  2. Can't use latest React Native. We're stuck using whatever version of RN the SDK requires, but we're increasingly relying on features in latest releases or nighties.
  3. Installs unnecessary dependencies. We don't need RNfWeb but Expo forces this for Web.
  4. Metro and Expo will lack StyleX integration on Web. I don't think we have a way to get the output from the StyleX CLI back into Expo.
  5. Expo controls the outer document and RN container, which limits our ability to prototype cross platform <body> etc components.
necolas commented 4 months ago

SDK bug report: https://github.com/expo/expo/issues/30143

EvanBacon commented 4 months ago
  1. Can't use latest React Native. We're stuck using whatever version of RN the SDK requires, but we're increasingly relying on features in latest releases or nighties.

Unclear what new features you're referring to here. Expo SDK 51 is the only reasonable way to access and use experimental React 19 features end-to-end on iOS, Android, and web (npx create-expo-app -e with-canary-react-19).

We also test the Expo SDK against nightlies, and support new architecture. You can change or patch dependencies in dev clients however you'd like.

  1. Installs unnecessary dependencies. We don't need RNfWeb but Expo forces this for Web.

It's unclear to me how installing react-native-web blocks usage with react-strict-dom. We enforce the installation of react-native-web to reduce the chance of errors on web and increase developer success. I'm more than willing to add a flag to support starting Metro web without react-native-web installed though.

  1. Metro and Expo will lack StyleX integration on Web. I don't think we have a way to get the output from the StyleX CLI back into Expo.

Expo CLI supports standard CSS, CSS Modules, Sass, SCSS, and postcss. Along with custom Metro transformers, there should be more than enough bundler API to build a StyleX plugin for Metro. Here's an example of a complex styling plugin from nativewind.

If something is missing here, please let us know and we'll fix it.

  1. Expo controls the outer document and RN container

Reasonable defaults are applied by default. You can create a public/index.html to overwrite the default value docs (run npx expo customize to interactively generate this file). You can use web/index.html for legacy Webpack projects, and the new app/+html.tsx for dynamically controlling the root during server rendering.

For the React Native container, simply create an index.js and register your own root component.

byCedric commented 4 months ago

Hi @necolas! I also followed-up on your bug report, I'd love to dig into the issues you mentioned! https://github.com/expo/expo/issues/30143#issuecomment-2206857308

necolas commented 4 months ago

Thanks @EvanBacon and @byCedric for all the pointers, we'll look through everything and try it out.

It's unclear to me how installing react-native-web blocks usage with react-strict-dom

We want to avoid react-native-web from being bundled, inserting styles, and handling root rendering.

Expo CLI supports standard CSS, CSS Modules, Sass, SCSS, and postcss

Is there a way to disable all this? It's not aligned with our vision for cross-platform code sharing, so if we were to provide a template based on Expo it would need to drop these features.

nmn commented 3 months ago

@EvanBacon I looked at the transformer for Nativewind web and I found the following code:

if (isWeb) {
  return worker.transform(
    config,
    projectRoot,
    filename,
    Buffer.from(`require('${config.nativewind.output}');`, "utf8"),
    options,
  );
}

This is not sufficient for StyleX as we need to the following steps:

  1. Transform each JS file and put the generated CSS into a file-specific metadata
  2. Once all the files are transformed, take all the style metadata and generate a CSS file

There can be a possible workaround if the require() can be used to import CSS data URL instead of a file import, like it does for Tailwind. Is this something supported?

necolas commented 2 months ago

I tried this out again, because we want to be able to test against RN 0.75 with the new architecture enabled.

Reinstalled the examples project from scratch following these instructions. First run of the start command:

Development build: Unable to get the default URI scheme for the project. Please make sure the expo-dev-client package is installed.

CommandError: No development build (com.example.with-new-arch) for this project is installed. Please make and install a development build on the device first.

The script did not install the dev client. I skip the dev-client flag. Second run

The following packages should be updated for best compatibility with the installed expo version:
  @expo/metro-runtime@3.2.1 - expected version: ~3.2.3
  expo@51.0.18 - expected version: ~51.0.31
  expo-build-properties@0.12.3 - expected version: ~0.12.5
  react-native@0.75.2 - expected version: 0.74.5
Your project may not work correctly until you install the expected versions of the packages.

The app runs fine, and I look at the examples to see if position:static is supported properly, as we expect on the new architecture. But it doesn't rendered properly (we've verified internally that it works internally on our app infra). Wondering how we can tell if the new architecture is actually enabled in the app, and why we don't see some of the features that should turn on - I can't really tell what is an Expo / setup issue vs what is a React Native / featureFlag issue.