Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Expo SDK in example #236

Closed
2 of 3 tasks
necolas opened this issue Nov 12, 2024 · 7 comments
Closed
2 of 3 tasks

Update Expo SDK in example #236

necolas opened this issue Nov 12, 2024 · 7 comments
Labels
help wanted Extra attention is needed

Comments

@necolas
Copy link
Contributor

necolas commented Nov 12, 2024

Update the Expo SDK

We use Expo to power the example / visual regression testing app. Keeping this up-to-date is important for the following reasons:

  1. We validate the experience of using RSD with the latest OSS RN releases.
  2. We do most RSD development in this repo, using OSS RN first.
  3. We want RSD to be easy to adopt when using Expo - the recommended OSS RN framework, and a React framework that is explicitly aligned with the goals of RSD.

The current challenges

  1. We are missing developer docs for process of upgrading Expo in the RSD repo. Make it easy for anyone to improve and follow the Expo upgrade process in the RSD repo.
  2. We don't have a working style extraction plugin for Metro on web. Make it so that Expo-based RSD apps can deliver static CSS files.

Action items

  • Update to SDK 52. Updating to SDK 52 is important for testing against the new RN architecture. The process should be documented for the future. Blocks #219 and #225.
  • New contributor docs. Add details to the "contributing" docs on how to maintain repo infra like Expo, Jest, etc. For Expo, I imagine it might contain links to guides like "Upgrade Expo SDK", and any other steps that may be specific to successfully upgrading the RSD repo.
  • Extract CSS in Expo. Look into the approach taken by @javascripter's postcss-react-strict-dom.

cc @ecreeth @javascripter

@necolas necolas added the help wanted Extra attention is needed label Nov 12, 2024
@necolas necolas pinned this issue Nov 12, 2024
necolas pushed a commit that referenced this issue Nov 13, 2024
@javascripter
Copy link
Contributor

javascripter commented Nov 13, 2024

I'm happy to help advance Expo CSS extraction sitaution!
Regarding the approach used by my plugin, here's the quick summary and the thinking behind the plugin:

Overview:

  • Detection: Scans imported CSS files to locate the @stylex at-rule directive,
    which acts as a placeholder for generated styles (expects only one such file).
  • Compilation: Transforms source files matching a specified glob pattern (from plugin options) using a Babel preset for RSD, collecting styles during this process.
  • Replacement: Replaces the @stylex directive in the CSS with the compiled CSS

Watch Mode:

  1. Dependency Tracking: Watches entire directories that may contain files needing transformation, not just those matching the glob pattern. This broader watching ensures reliable detection of added or deleted files during development (PostCSS CLI can't reliably detect new files added in watch mode)
    • Expo Web uses its own dependency tracking (uses source code dependencies I think) so it doesn't use PostCSS file dependencies, but Step 2 and below apply the same)
    • For a glob pattern ./src/**/*.{ts,tsx}, the PostCSS plugin watches the entire ./src directory to trigger Step 2
  2. Re-globbing: Upon detecting changes, the plugin re-globs all files matching the pattern.
  3. File change detection: Compares Last-Modified timestamps to identify new or changed files since the last run and re-runs Babel for those files.
  4. Recompilation: Re-compiles the collected styles and updates the CSS placeholder with the new styles.
  5. Re-subscribing: Continues watching the same dependencies for subsequent changes.

Design Considerations:

  • Consistency: Reuses the project's Babel configuration by default; Bundler handles transpilation as is, while PostCSS uses the same babel config to extract CSS for the files manually specified by the globs (bypassing the need to resolve path aliases, monorepo dependencies, node_modules resolution etc).

  • Potential for Caching: Sharing the same Babel configuration may allow for the future possibility of reusing the Babel cache with the bundler to improve performance (cache implementation is pending). If that proves infeasible it can still maintain its own babel cache across builds

  • Simplified logic: Relies on Last-Modified timestamps and re-runs the process uniformly on file changes. This simplifies reasoning about the plugin's behavior and makes testing more straightforward.

  • Recoverability: If the plugin misses changes during watch mode due to unforeseen issues, it will re-synchronize on the next file save, ensuring the generated styles stay consistent with the source code.

@necolas
Copy link
Contributor Author

necolas commented Nov 14, 2024

Thanks, that explanation is very helpful. It looks like a pretty good approach. I'm happy to use it in the example app. Does postcss automatically get run during the Expo and Next build process?

@javascripter
Copy link
Contributor

Thanks, that explanation is very helpful. It looks like a pretty good approach. I'm happy to use it in the example app. Does postcss automatically get run during the Expo and Next build process?

Yes, both Expo and Next.js run PostCSS automatically, so the generated CSS will be bundled automatically on builds/dev.

It isn't relevant to Expo Web usage but Next.js has a known next/babel compatibility issue with App Dir so my plugin usage with Next.js is more experimental.

I'll look into configuring the example app to use my plugin and send a PR!

@necolas
Copy link
Contributor Author

necolas commented Nov 14, 2024

One thing I noticed is that it would be good if the plugin internally included the RSD package in its "include" paths array so users don't have to point to internals

necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236

Co-authored-by: Tsubasa Sakai <javascripter@tsukkun.net>
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236

Co-authored-by: Tsubasa Sakai <javascripter@tsukkun.net>
necolas added a commit that referenced this issue Nov 14, 2024
Extract styles to static CSS using postcss, as there is no existing
Metro integration.

Fix #34
Ref #236

Co-authored-by: Tsubasa Sakai <javascripter@tsukkun.net>
@necolas
Copy link
Contributor Author

necolas commented Nov 14, 2024

Thank you very much @ecreeth @javascripter for the quick help and excellent work! I'll work on the last piece, the extra docs, and let you know when that's ready for review

@necolas
Copy link
Contributor Author

necolas commented Nov 14, 2024

One more thing I'd like to do is make the Expo example a proper Expo app, e.g., using whatever universal routing system they ship these days. We could even have a create-react-strict-dom package that can be used to set up a working RSD/Expo project using npm create

@necolas necolas unpinned this issue Nov 19, 2024
@javascripter
Copy link
Contributor

javascripter commented Nov 22, 2024

Is there still interest in providing Next.js example for RSD as well?

I created a demo for Next.js 15 with RSD using postcss-react-strict-dom plugin below.
https://github.com/javascripter/nextjs-react-strict-dom-demo/

Quick summary:

  • Uses Babel, PostCSS and Webpack. Setup is quite similar to Expo Web.
  • Supports App Dir and in my testing works for real apps (running on production)
  • Server Actions do now work while next/font does not (due to next.js limitation)
  • stylex-webpack has performance issues related to StyleX rule data serialization/deserialization from/to URL search query. This does not rely on that and we're seeing dev mode performance improvements (depends on project size/setup)
  • Does not rely on Next.js internals and users can enable new features like React Compiler on top of this as well

The output seems to be an exact match, except for the last image loading text which doesn't show in my example(I haven't examined yet).
Screenshot 2024-11-22 at 19 07 59

@nmn The same technique can be used to develop StyleX PostCSS Plugin as well I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants