https://github.com/javascripter/stylex-expo
StyleX & React Strict DOM integration with Expo for Web with Static CSS extraction
https://github.com/javascripter/stylex-expo
react-strict-dom stylex
Last synced: 5 months ago
JSON representation
StyleX & React Strict DOM integration with Expo for Web with Static CSS extraction
- Host: GitHub
- URL: https://github.com/javascripter/stylex-expo
- Owner: javascripter
- License: mit
- Created: 2024-04-11T13:26:37.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-07T12:47:40.000Z (about 1 year ago)
- Last Synced: 2024-08-07T15:29:05.668Z (about 1 year ago)
- Topics: react-strict-dom, stylex
- Language: JavaScript
- Homepage:
- Size: 274 KB
- Stars: 6
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# StyleX for Expo Web (Experimental)
StyleX & React Strict DOM integration with Expo for Web.
_Not intended for production for now._
This repository demonstrates how to integrate StyleX / React Strict DOM for
Expo, with support for **Static CSS Extraction** in Expo Web.The official react-strict-dom repository app does not support extracting css files and injects CSS in runtime, which this repository tries to fix.
Please see [this issue](https://github.com/facebook/react-strict-dom/issues/34) for more context.## What works?
- Production CSS extraction
- Dev mode Fast Refresh
- iOS & Android (does nothing)## How to run
`yarn install`, then:- web:
- `yarn web` for developing web with Fast Refresh
- `yarn expo export -p web` for production builds with static css file in
dist.
- native: `yarn ios` or `yarn android`.You can also use `yarn start` to develop for multiple platforms simultaneously.
## How does it work?
`withStyleX` Metro Plugin in configured in `metro.config.js`.
You can see the source code for `withStyleX` plugin in `stylex-metro-config`
directory.Basic explanation:
1. Each JS file containing stylex imports is transformed using `@stylexjs/babel-plugin` in
`stylex-metro-config/transformer.js` and stylex metadata for each file is
directly injected in each file with `import
'stylex.virtual.css?filename=...&contents=...'`, where stylex rules and filename
are encoded in search params.2. Then, the resolver in `stylex-metro-config/index.js` will look for these imports
and store these stylex rules.
3. The resulting css is written to `node_modules/.cache/stylex-metro-config/stylex.bundle.css`,
while resolving all `stylex.virtual.css?` virtual module imports to this file.There are a few limitations/questions I'm aware of:
- CSS files are written many times in the resolver
- Maybe we can debounce in dev, but in production we may need to resolve synchronously?
- Or, maybe this should be done in the serializer? I'm not too sure either.
- In dev, is it better/faster to use the original babel plugin runtime injection in web rather than writing to .css?
- No bare RN support
- CSS support is implemented in the Expo framework only
- Not sure if this works without Expo Router
- Not sure if this works with bundle-splitting and static/server-rendering (haven't investigated yet).## Monorepo usage
Follow Expo's guide on monorepos [here](https://docs.expo.dev/guides/monorepos/).
Make sure you pass the `projectRoot` to `withStylex`. Here's a working metro config:
```ts
import { getDefaultConfig } from "expo/metro-config";
import { withStyleX } from "stylex-metro-config";
import path from "path";// Find the project and workspace directories
const projectRoot = __dirname;
// This can be replaced with `find-yarn-workspace-root`
const monorepoRoot = path.resolve(projectRoot, "../..");const config = getDefaultConfig(projectRoot);
// 1. Watch all files within the monorepo
config.watchFolders = [monorepoRoot];
// 2. Let Metro know where to resolve packages and in what order
config.resolver!.nodeModulesPaths = [
path.resolve(projectRoot, "node_modules"),
path.resolve(monorepoRoot, "node_modules"),
];module.exports = withStyleX(config, {
projectRoot, // important
});
```