Hello,
First of all thanks for your amazing library 鉂わ笍
We have a monorepo and some of the libraries like "api clients" needs to be built for react native and also web. I suppose like both node and web targets
Is there a way to achieve that in tsdx?
Thanks
I'm not an expert in this as I haven't necessarily built that much for both targets, but if this isn't a component library, it shouldn't be much different from targeting web.
Some examples:
mst-persist that's used often in RN contexts (I use it in RN too). There's some docs on AsyncStorage but otherwise works the same on web and RN.redux-toolkit doesn't seem to handle the RN case any differentlyimmer sets the react-native field in package.json to its ESM buildmobx-react has a tiny little script that copies the ESM build and replaces react-dom with react-native. It sets the react-native field to that copy.I think "api clients" should for the most part be fine with that approach, but RN's fetch handling can sometimes be different from the browser due to how the native implementation works.
If you're using Hermes or an older RN Android (< v0.59), then you may have some issues with the environment as it doesn't support things like Proxies for instance, so you'd want to make sure if you're compatible (Proxies have no polyfill, but for most ES6+ features, you'd just want to transpile down to ES5 by setting your preset-env config accordingly).
Immer explicitly notes this in its installation docs. Recently it made the ES5 fallback opt-in (for smaller bundle sizes), but previously it was always included.
For component libraries you'd probably want to use something like react-native-web or build two separate variants.
What your library may or may not have to do to support RN is a case-by-case basis, so I'm not sure there's one single "Best practice" TSDX could recommend.
I have the same question. Not really about "best practice" per se, but how to build a universal component library with React Native Web using TSDX and have 2 example folders: web and native.
Bonus point if Storybook is included.
I struggled with this from react-with-storybook template for a couple of hours tonight but couldn't come up with anything satisfactory.
@alexluong I do think that's separate from OP's intro as they said for "building" and "API clients", not for examples and components (and doesn't mention RNW).
But to answer the question, you could probably make the current example dir examples/web/ and add an examples/react-native/ dir that uses Expo.
Alternatively could make them both with Expo since it has some support for web builds nowaday -- depends on what you think your consumers are more likely to use for web.
Regarding Storybook, there is Storybook for React Native that you'd probably want to use.
PR welcome to add either to the templates, as we've had a small bit of RN interest and RN is typically more complicated where template/example could be helpful.
Thanks a lot @agilgur5 for the detailed explanation. I'm quite new in react-native as well so I didn't know about "react-native": '/dist/esm.js'.
I did some tests and by default it gets the "main" field of the package.json if react-native is not present. Good to know :) Both bundles works fine in RN indeed.
Many thanks also for the links and resources.
Most helpful comment
I'm not an expert in this as I haven't necessarily built that much for both targets, but if this isn't a component library, it shouldn't be much different from targeting web.
Some examples:
mst-persistthat's used often in RN contexts (I use it in RN too). There's some docs onAsyncStoragebut otherwise works the same on web and RN.redux-toolkitdoesn't seem to handle the RN case any differentlyimmersets thereact-nativefield inpackage.jsonto its ESM buildmobx-reacthas a tiny little script that copies the ESM build and replacesreact-domwithreact-native. It sets thereact-nativefield to that copy.I think "api clients" should for the most part be fine with that approach, but RN's
fetchhandling can sometimes be different from the browser due to how the native implementation works.If you're using Hermes or an older RN Android (< v0.59), then you may have some issues with the environment as it doesn't support things like Proxies for instance, so you'd want to make sure if you're compatible (Proxies have no polyfill, but for most ES6+ features, you'd just want to transpile down to ES5 by setting your
preset-envconfig accordingly).Immer explicitly notes this in its installation docs. Recently it made the ES5 fallback opt-in (for smaller bundle sizes), but previously it was always included.
For component libraries you'd probably want to use something like
react-native-webor build two separate variants.What your library may or may not have to do to support RN is a case-by-case basis, so I'm not sure there's one single "Best practice" TSDX could recommend.