Closed kelset closed 5 years ago
Make the codebase more approachable
I don't know that this will necessarily be the case. If code ends up being spread throughout many modules and repos, it's going to be hard to find exactly the code we're looking for. Having the React Native renderer in the React repo is already an example of this. It's trivial to search the repo now for the specific component you're looking for and find all the code related to it.
Reduce the Bundle size for projects that don't use the "extractable" components, which would lead to faster startup times for the apps
I believe we can accomplish this in ways that don't include separating code in the repo.
Have we explored using Lerna or Yarn workspaces to help alleviate some of this?
👋 @eliperkins I see you points, just want to underline how this is a temp post while the proposal is being written up :)
You should discuss those points there once it's up (which should be soon, @axe-fb is writing it AFAIK).
I think components like ScrollView
which are absolutely necessary when building any app should remain in the core. Separating components such as WebView
, ViewPager
, DrawerLayoutAndroid
etc. make sense.
Reduce the Bundle size for projects that don't use the "extractable" components, which would lead to faster startup times for the apps
Metro should support tree-shaking. Then RN can use ES exports which will reduce the bundle size for JavaScript code that's not used.
For native code, on iOS, devs have to include the modules they are going to use, not sure why this isn't the case on Android. But it would help to reduce the native code size.
@kelset - I started working on a proposal, but I think that each Native Module and View Manager may be slightly different. Instead of writing one blanket proposal for all components, I think it will be more actionable to write up proposal for sets of components.
I am thinking that the work itself could be done in two phases. Here is a set of Native Modules that I have looked at.
Remove all components that we think can be deprecated. This is the rows in yellow.
Remove maintained components out of the repo.
Make upgrading easier - today, a breaking change in ONE component prevents teams from upgrading entire React Native. With massive changes like Fabric, we need the ability to be able to continue upgrading React-Native core, and allowing gradual upgrades of things like native modules.
Faster PRs and responding to issues. Though we tag issues and PRs, at this point it seems a lot. Also, moving components outside will also enable other contributors merge in PRs faster. Given the surface of React Native, we do need more help, and need to add to core contributors.
@eliperkins - Thanks for taking a look at the idea. I did look into Lerna workspaces. While it is potentially useful for typical cases of testing, I am not sure how it would really benefit during development. As I understand, most people typically work on a single component at a time, and having the ability to have a simple RN app with just that component may make it more manageable, and will also be easier to get started with.
It's trivial to search the repo now for the specific component you're looking for and find all the code related to it.
I would like to believe that in most cases, the code of a component or native module should live at one single place. Today, JS and Native code is separated, which makes it harder. But putting them all in one repo, it would be much easier to develop/debug.
Having the React Native renderer in the React repo is already an example of this.
I think you are right. We would like to eventually like to move to a world where React is the top level repo, and REact-dom is a renderer, just like React-native, or React-VR. I think that by separating core from components and native modules would help with that.
Bundle Size
Also be making core components like ScrollView
or Flatlist
at the same level as other components, we can ensure that people who don't use core components remove them like regular components.
If you think these explanations don't make sense, please let me know - I can try to elaborate !!
@satya164 Could you please explain "tree-shaking" ? Could you also please explain the point about "For native code, on iOS, devs have to include the modules they are going to use, not sure why this isn't the case on Android. But it would help to reduce the native code size" ?
@axe-fb
Tree-shaking is when the bundler marks unused imports as dead code which is then removed by the uglifier. Since ES imports are statically analyzable, it's easy to detect which modules are unused and mark them as dead code. All the major bundlers on the web support it, such as Webpack, Rollup, and Parcel. Rollup and Parcel also support tree-shaking on CommonJS modules. Metro doesn't support this feature.
So when you start a React Native iOS project, not all of the native modules and components are linked by default. If you want to use a native module that's not linked by default, you need to link it manually (for example the blob module on iOS is not linked by default). Whereas on Android all of the available native modules and components are already linked by default.
We used Lerna on a project (https://github.com/infinitered/gluegun) and, while it's a very cool system, I found it wasn't really worth the extra confusion it generated among new contributors.
I remember a year ago or so, someone came up with a list of the components that every renderer needed to support if they were going to be able to able to render an app. It was things like View
and Text
. As I recall, there were around 7 components and a handful of APIs plus the bridge. I think the list may have been put together by the person who built react-native-xp
but my google-fu is weak today so I can't find it
All of that to say, it seems like the React Native repo should have the minimal list of components/APIs/code required for every app and then everything else should be in a separate repo
At React Native EU today there was a conversation with some of the core contributors around why we haven't removed NavigatorIOS yet. The answer was that it is part of the slimmening effort but just nobody had done it yet.
@fkgozali just put up an internal commit removing it from React Native. That will be landing shortly.
put up an internal commit removing it from React Native. That will be landing shortly.
here’s the commit: https://github.com/facebook/react-native/commit/0df92afc1caf96100013935d50bdde359b688658
Expect a properly written PR with the proposal for it, this is a "temporary" post for transparency purposes.
@kelset is this still planned?
No, actually 😅
I'm planning on reworking the top post a bit (based on a couple things discussed during RNEU) but haven't had time yet 🙈 Will do it this week
@turnrye - I think we don't need a top level PR. We could have PRs for individual components that we want to remove and move out - like what we did for webview.
I've updated the top post, let me know / let's discuss about how to make the slimmening better.
Thank you for updating the original issue @kelset with some recent changes we have discussed together.
Generally speaking, I really like the direction we are moving towards. I have one comment on the roadmap for deprecating and eventually, removing modules from the core.
As a part of the first step (listed below):
version N: the proposal gets merged, new repo gets created and changelog communicates it
I would also think about removing the module that is the subject of a particular extraction and requiring it from the new module right away. That way, we would automatically opt-in everyone for the latest version of a particular module and make it easy to verify that the newly created API and established release process works without issues.
I would imagine we could print a deprecation message along the following lines:
WebView has been moved away from React Native core to
react-native-web-view
package. This version of React Native required that package for you behind the scenes. In the next version, you will have to change your imports to access WebView from that package instead.
@kelset ,NavigatorIOS will be removed in rn-0.58,would you put it in facebookarchive/react-native-custom-components
@linjson I suggest you do it yourself if you still need that component. Or maintain your own version of it.
Does anybody have a rough estimate for impact on bundle size & startup time when removing NavigatorIOS + WebView?
@ricardobeat This tweet by @fkgozali suggests that with NavigatorIOS removed, the savings should be 20kb+. I guess @jamonholmgren would have more info on the webview savings once he has extracted it from core and deleted the necessary code.
That said, since those two extractions will happen as separate times (the full extraction of WebView won't happen in 0.58) I don't think it's too relevant to get a combined "benchmark".
I don't currently have an estimate on savings, but that would be interesting to know.
There's two problems:
Does moving away from the current monorepo solve these problems?
Anecdotally, I've seen separation into many repositories come with problems: it's significantly difficult to perform integration tests, and a non-trivial amount of time is spent assuring versions of packages align -- even with decent tooling. Versioning then becomes a developer concern (although, I guess this is normal in JS projects). Then there's the problem of discoverability: where do folks find the de facto WebView? Can developers easily find the right component?
Just some initial thoughts. Glad to hear this stuff’s being carefully considered.
@gwmccull
I remember a year ago or so, someone came up with a list of the components that every renderer needed to support if they were going to be able to able to render an app. It was things like
View
andText
...All of that to say, it seems like the React Native repo should have the minimal list of components/APIs/code required for every app and then everything else should be in a separate repo
You are referring to then-Airbnb engineer Leland Richardson's React Primitives concept. Those components were:
Animated
: Pulled from the animated project.StyleSheet
: Follows React Native's StyleSheet API.View
: A base component for Layout.Text
: A base component for Text rendering.Image
: A base component for Image rendering.Touchable
: A base component for interaction.Easing
: A base set of easing functions.Dimensions
: Get the devices dimensions.PixelRatio
: Get the devices pixel density.Platform
: Get information about the platform. (iOS, Android, Web, Sketch, VR,...)(With consideration for TextInput
as a possibility in future).
My concern for The Slimmening is that components lose sync with a particular version of RN. We need a clear system to communicate which versions of the components are properly supported by which versions of RN and React. I'm always stuck using older versions of RN (because I'm developing for react-native-macos) so I worry about the hell of finding a compatible version of a component to adopt, especially if community repositories start using bleeding-edge versions of React.
Any plans to make NavigatorIOS
available as a new package?
What's the distinction between Deprecate for community
and Move to community module
? The former seems to only have been used for PushNotificationIOS
as far as I can tell. Is the intention the same or is it supposed to mean something different?
I'm glad this conversation and this push are happening. I think it is absolutely necessary and I know the rest of the RN team at Facebook feels the same way. I'd like to offer some of my thoughts, and it is definitely something I'd love to help with a lot in 2019. Currently I'm removing the local-cli
from RN in an effort to reduce the repo size.
So far the conversation has focused mostly on UI/Native modules, and on moving things out to other places. If we look at the overall problems we have and could solve under this effort, there are many:
Based on this I propose to broaden the scope of this effort to make React Native leaner on all fronts. We could look at all the ways we can make React Native better for users and developers by removing complexity instead of adding it. I'm not saying that this wasn't your plan all along, I'm mostly just trying to help you shape the narrative of this effort. We at FB would like to make sure this effort contributes to an eventual stable release of React Native that we can all be proud of.
Second, I would like to add some structure about this effort by making a list of all the work that can be a part of this effort, and it would be great to start a master task on RN to track and push the effort. I know there is a gdoc somewhere but I don't think many people look at it. Let's put together a list, prioritize, and then tackle all of the things we set out to do in 2019.
Finally, as I have pointed out previously, "Slimmening" is not a real word and it sounds a bit off. What do you think about choosing a different name? Here are some my silly suggestions, but please come up with your own:
What do you think?
What about "React Native One" as once everything here is done we could think about releasing it out of beta 🤔 ?
That’s a good idea. However, I think there is more to “1.0” than in the effort outlined above so tying them together may not be a good thing.
Side note: Maybe it makes sense to think of what it takes for React Native to become "1.0" and start working towards that goal. Community organisation & the process of making it smaller are definitely big parts of that.
Ok so, lot of things to unpack here:
Based on this I propose to broaden the scope of this effort to make React Native leaner on all fronts. We could look at all the ways we can make React Native better for users and developers by removing complexity instead of adding it.
Because the second phrase seems to suggest that we are adding complexity (how?), but at the same time your proposal is to broaden the scope, and that broadening the scope would reduce complexity? I am not sure I understand this part correctly. 🤔
Second, I would like to add some structure about this effort by making a list of all the work that can be a part of this effort, and it would be great to start a master task on RN to track and push the effort.
But with should that "meta" task live on the main repo? Were you thinking of using Milestones for that, or the Project section? Or even the Wiki part? 🤔
and write them in a Readme or howto or something so that everyone will have a "source of truth" for that.
Finally, as I have pointed out previously, "Slimmening" is not a real word and it sounds a bit off. What do you think about choosing a different name?
As a not english mother tongue this name never sounded off to me, I always felt that its the fact that it was made-up helped labelling it as a "codeword" and conveyed the concept of the effort. But if you want to change it, it's fine by me. As the Poet would say
What’s in a name? that which we call a rose By any other name would smell as sweet
@kelset thanks for updating the top post. I took the liberty to rename the title of the issue.
I'm sorry for confusing you. The sentence about complexity was meant to say that everything should be part of the Lean Core that is under the umbrella of removing complexity in some form or another, instead of looking only at specific ways to reduce complexity (like, making Lean Core only about runtime dependencies, for example). I was just pointing out that Lean Core should be all encompassing.
I quite like "Master Tasks" on the main repo. That way we can outline the beginning and end of the project in a way that is easy for people to track. I'm fine with using milestones or projects too, it's up to you.
Totally agree that we need a process. Would you like to spend some time on outlining the concrete process?
List of modules
Is it worth drawing up a list of which parts of the RN core are staying and what is happening to the others? A good place to start is all of the directories in the Libraries
folder or the list of APIs in the documentation.
Extracted module names
It would also be good to discuss what name the community modules will be published under. Taking NetInfo
as an example there are some possible module names:
react-native-netinfo
- Currently taken by a module with a completely different API. Basically a component wrapper around NetInfo
itself.react-native-net-info
- Not taken, but easy to mistake for another package.@react-native/netinfo
- Not sure if this is possible, but it keeps the extracted modules closer to the core of React Native and makes them "official".@react-native-community/netinfo
- This would follow the convention that the extracted CLI has started.Is maskedviewios
also being considered to be moved out from the core repo ?
@matt-oakes @kaushikwavhal there is a link in the first issue to a Google Sheet file with the list of the items that are being considered.
re: module names: there have been already some conversation about those things, but we don't own all those variations. I think that for the CLI we may use the @react-native one but can't recall - cc @grabbou
@kelset Whoops! I completely missed that Google Docs link. My bad.
re: module names: there have been already some conversation about those things, but we don't own all those variations. I think that for the CLI we may use the @react-native one but can't recall - cc @grabbou
There have been some issues with the @react-native
scope and we ended up using @react-native-community/cli
in our case. I think it's a good scope to be used for the rest of packages too.
Thank you everyone for this long discussion. It's super exciting that we'll be able to remove so much cruft from React Native. I went ahead to start an umbrella task to track all the concrete work: https://github.com/facebook/react-native/issues/23313
I will close this issue as I believe we have reached consensus both about what we want to do and we have a rough idea on how we want to do it. @axe-fb I want to especially thank you for doing all the work to identify a lot of the things that can be removed or moved out of React Native.
Please feel free to keep commenting here for further discussion or to bring other things to our attention that we haven't thought about removing yet.
@kelset I don't think it's necessary to submit a PR with a proposal to this repo, but if you'd like to do that still then that's alright with me.
Are there any plans to have navigatorIos
as a community package? Our project currently depends on it and i would be interested in migrating it to a separate repo. @fkgozali
@michaelknoch NavigatorIOS was removed entirely from React Native. We suggest using more modern navigation solutions. If you want to keep using Navigator IOS, when upgrading to 0.59, you'll have to either drop it or build your own legacy fork of the component. Please check the react-native repo at 0.58 stable and extract NavigatorIOS on your own and put it into your own repo.
the lack of an inbuilt navigation solution for react-native is probably the largest blind spot. any app containing functionality beyond the most trivial use cases will require navigation, and while there are 2 major open source options to fill this role, they both come with their own pitfalls and drawbacks that add cognitive overhead and make RN less approachable.
seeing further pieces of RN stripped off in this manner feels like a step backwards to me. I can certainly appreciate the reasoning behind it, and hell I even agree with that reasoning in a lot of ways and on several points, but I fear that the practical effect will be a net negative on the usability and approachability of RN.
just keeping react, react-native, and flow-bin versions synced can be a bit of a headache already... now multiply that a few times and you're looking at a 24/7 blinding migraine.
@ericketts - as someone currently experiencing a migraine, albeit for unrelated reasons, i feel your pain.
also as a maintainer of one of the navigation solutions, i see where you're coming from - asyncstorage and maskedviewios are now two more libraries that we'll need users to install, or we need to instead remove the features that they provide and require users to inject their own tools to do their jobs. that said, i can't see how it would be any better if navigation itself was internal to the react-native repository. it used to be, and it just slowed down iteration speed and made other navigators seem like secondary options because they weren't "blessed" by being part of core, regardless of their merit. further, i think we need to accept the reality that facebook has no interest in maintaining a large react-native core that includes code that they don't use in their apps.
i work on expo and we provide a large set of apis out of the box, and we're also including the packages that are being split out of core (a few will go into our next release in a few weeks or so). in my opinion expo can help a lot with approachability of react-native. other tools like ignite provide opinionated boilerplates and are another reasonable alternative. in general there's an opportunity for the community to build end-to-end frameworks around react-native. react-native will end up as the rendering/plugin layer, and the pieces that are built on top of it will be up to individuals and companies in the community.
my only fear is that the instability from core that we have seen since the start will continue, and folks working with react-native will become fatigued with keeping up to breaking changes and regressions. i imagine it'll get worse before it gets better, with turbomodules and fabric coming and representing a significant change to core, but if this helps us get to a point where the core can be relatively stable it'll be worth it.
i think we need to accept the reality that facebook has no interest in maintaining a large react-native core that includes code that they don't use in their apps
yeah this is really the truth, despite sometimes in the past my trying to pretend its not haha. it also scares the hell out of me for the future of RN as a whole if facebook ever decided that native only is their path forward. I hope the community could and would step up, and I guess this will be something of a test of the potential for that (eventuality of that?) (also you guys at expo are doing some great work for lowering barrier to entry on RN, and I thank you for it, despite having decided to go with a more piecemeal solution for various reasons (some of which contain a bit of irony given the position of my previous post, so I'll edit them... for brevity)).
as you @brentvatne say and I agree, there will likely be growing pains here, and I still have concerns about this project (both on the tech and human sides of the undertaking and results thereof); but there's also a lot of growth going on with RN that looks quite promising, still much to be excited about on the horizon.
I just wanted to get my few cents in, I know others had expressed some of my concerns more succinctly, but the conversation still seemed a bit more in the "yea" camp, so I'll throw my cautious "ehhh..?" into the books.
edit: also hoping your head feels better soon mate, those things are the worst.
the lack of an inbuilt navigation solution for react-native is probably the largest blind spot. any app containing functionality beyond the most trivial use cases will require navigation, and while there are 2 major open source options to fill this role, they both come with their own pitfalls and drawbacks that add cognitive overhead and make RN less approachable.
Let's have this discussion somewhere else, this is not part of the Lean Core process. I understand your frustration but @brentvatne made a great reply.
seeing further pieces of RN stripped off in this manner feels like a step backwards to me. I can certainly appreciate the reasoning behind it, and hell I even agree with that reasoning in a lot of ways and on several points, but I fear that the practical effect will be a net negative on the usability and approachability of RN. just keeping react, react-native, and flow-bin versions synced can be a bit of a headache already... now multiply that a few times and you're looking at a 24/7 blinding migraine.
I agree it may sound counterintuitive but if you look at webview, they (cc @Titozzz) actually managed to merge more than 100 PRs since it's extraction: https://github.com/react-native-community/react-native-webview
Other components like react-native-cli and react-native-netinfo are also success stories: useful modules will find awesome dedicated maintainers who can spend more time on solving a well-scoped problem than we could by mixing everything together. For some of these modules, this is the first time they are receiving real attention. Similarly, this effort also allows us to do a much better job at managing the React Native repo itself. As you can see, the number of open issues and pull requests is as low as it was when React Native was initially open sourced!
I realize though as you point out that there my be a small period of pain until we get everything into order. The new autolinking of native dependencies that will likely be part of 0.60 will help ease the pain though. We won't remove any actual components until then (except WebView).
All that being said: if something is extremely important to people and the separation is causing pain to the community we will consider bringing the module back into core. That reversal would also be a much simpler process :)
(this is slightly off topic so skip it if you're trying to follow the thread)
@ericketts
(also you guys at expo are doing some great work for lowering barrier to entry on RN, and I thank you for it, despite having decided to go with a more piecemeal solution for various reasons (some of which contain a bit of irony given the position of my previous post, so I'll edit them... for brevity)).
we're working towards making expo both a cohesive end-to-end tool while also letting folks who don't want that opt-in in a piecemeal style - more on that in https://blog.expo.io/you-can-now-use-expo-apis-in-any-react-native-app-7c3a93041331.
@michaelknoch what did you guys end up doing re: NavigatorIOS
? We have a legacy app that stopped compiling, so we updated react-native only to find NavigatorIOS "deprecated" and "removed". At this point I just want to get the app working again so I can make minor changes.
How is the removal of Webview going to affect those who use RN with Expo. From what i have seen the alternative of using react-native-webview requires linking which isn't possible with Expo? Is there a timeframe on when Webview is being dropped from RN?
@Shpadoinkle Presumably Expo will include the webview plugin by default like it includes various other native plugins.
https://facebook.github.io/react-native/docs/webview#source https://facebook.github.io/react-native/docs/webview.html#html
// old
import { WebView } from "react-native";
https://github.com/react-native-community/react-native-webview/blob/master/docs/Getting-Started.md https://github.com/react-native-community/react-native-webview
# install
$ yarn add react-native-webview
# link
$ react-native link react-native-webview
// new
import { WebView } from "react-native-webview";
Intro
With this issue I'd like to try and create a "one stop" for all the information available around the discussion that has been going on for a long time within the Core team about this project - and explain the label.
The Gist of it
React Native is currently a huge repo. Would it make sense to move UI components (ScrollView, Switches, WebView) and Native Modules like PushNotifications, etc into a separate repos?
The basic answer is yes, and in the past few months this has started becoming a reality via a few proposals and some commits from the FB team.
You can check the full list of native components that are being considered for extraction/deprecation here, but proposals can also be about JS-only components.
Advantages
Doubts (with "answers" to discuss about)
A) Should we define a roadmap that each "separation" will have to follow?
The rough rule, for now, is to follow this set of steps:
For "pure removal" of old code, this may happen in a "2 version" window instead (ex. the old
NavigatorIOS
, removal announced in 57 and will happen in 58).This is still a WIP so feedback on how to make it better is appreciated. Ideally we'd have a dedicated document with the details on how the flow of an extraction works, so that everyone on the community can understand all the steps involved and can take ownership of a proposal for an extraction.
B) How would this affect platforms like React-native-windows?
Owners of those out-of-tree platforms should be involved in the conversations to ensure a smooth transition.
B1) What's the best way to ensure that Expo is not left behind when the components are moved outside?
C) Who would retain ownership (and "responsibility to maintain") the separated component?
For "extractions", the new repositories will live under the
react-native-community
umbrella. Details around npm deployment are still being discussed, expect a dedicated issue about that.For "deprecations/removals" they will be probably be just removed from the main repo, and eventually "ported" to this repository for deprecated-modules by FB by developers that still need it.
EDIT: this has been massively edited to provide more informations about the slimmening and reflect the ongoing discussion. And since things are still moving, please keep an eye on this post because it will evolve more.