facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
116.48k stars 24.01k forks source link

☂️ Lean Core #23313

Closed cpojer closed 3 years ago

cpojer commented 5 years ago

For the past several months we have been discussing and making progress on a project called “Lean Core”. Please read our motivation for this project. Over the years React Native has accumulated a lot of parts that are now outdated, unused or otherwise legacy. It's time to clean everything up and put the repository into a much more manageable state going forward.

This is an umbrella task intended to track all the work necessary to reach the goal of a leaner core, including work around repository reorganization. This issue is being kept up to date so new items will be added and completed ones will be (re)moved. Some of the items will spawn separate issues to track work. If you don't see a name assigned to any of the below items and you would like to help out, please volunteer in the comments and reach out to me to get started!

Components & Runtime

React Native currently comes with a large number of components, many of which are deprecated or outdated but they still part of the repository and increase the size of applications. For items in this section we are either looking to completely remove things if they are unused, or we'd like to move them either to community managed repositories or otherwise to facebookarchive. The list here is partially based on an awesome investigation by @axe-fb. The migration can be done roughly by following @matt-oakes's guide from further below: https://github.com/facebook/react-native/issues/23313#issuecomment-461462981

Third-Party Dependencies

Over the years we have amassed a large amount of dependencies, especially JavaScript. We have also moved things out of React Native, like Metro and the react-native-cli. This means we left a large amount of tooling dependencies in our package.json, many of which will are unused by RN itself and won't be updated to the latest versions, causing the full install of React Native to be bloated. It would also be great to do an audit of all the dependencies that are used and identify which ones could be removed.

Repository Structure

Right now the React Native repository is a large repository with little organization that promotes separation of concerns. It is our goal as part of this effort to also move things into a more manageable structure. As part of this, we'd like to follow a monorepo model that consists of multiple smaller packages. This will be a gradual migration and we will only be tracking the initial work to get this off the ground.

Completed work

Click to see prior work before this issue was created * [WebView extraction](https://github.com/react-native-community/react-native-webview) * [ListView and SwipeableListView](https://github.com/facebook/react-native/blob/master/Libraries/react-native/react-native-implementation.js#L62-L66) deprecations * [CLI extraction into a separate repository](https://github.com/react-native-community/react-native-cli) * [Removed BackAndroid](https://github.com/facebook/react-native/commit/774cd736633e652429e2d2c4a149763921b4e4da) * [Removed TabbarIOS](https://github.com/facebook/react-native/commit/02697291ff41ddfac5b85d886e9cafa0261c8b98) * [Removed NavigatorIOS](https://github.com/facebook/react-native/commit/0df92afc1caf96100013935d50bdde359b688658)
jdmunro commented 5 years ago

@cpojer I'd like to remove SnapshotViewIOS 🔪

krizzu commented 5 years ago

Hey @cpojer, thanks for putting it all together!

I'm willing to tackle few issues, starting from moving AsyncStorage.

matt-oakes commented 5 years ago

I would be happy to help with moving NetInfo to a community repo.

Would it be best to create a personal Github repo first and then potentially migrate that to the react-native-community org once it's ready, or should we start right away with a repo in that org?

wellmonge commented 5 years ago

@cpojer, I'd like to help at some of this issues, could I start with "Merge AlertIOS with Alert"?

cpojer commented 5 years ago

That's awesome! I put your names down next to the items above.

@jdmunro can you send a PR and assign me to it? Then I can take it over and remove FB specific stuff before landing. @Krizzu and @matt-oakes I created https://github.com/react-native-community/react-native-async-storage and https://github.com/react-native-community/react-native-netinfo for you to send PRs against with all the code necessary to make them third-party modules. Ideally in the first step, you'll just take the code from the RN repo and put them in separate repos. In order to ensure it works, we could then link them back into RN as a dependency and remove the original implementation. Further down the line we can actually move it to an optional package. @wellmonge Sounds great! I'm not sure entirely what the work will entail but maybe you can just check out the two modules and see if you can unify them?

michalchudziak commented 5 years ago

@cpojer I could help with moving slider 🙂

After that I can pick up something else if you’ll still need some help

cpojer commented 5 years ago

@michalchudziak Awesome! I created https://github.com/react-native-community/react-native-slider, please see my comment above on what to do next.

As a name for the project in package.json, please use @react-native-community/<project name>, ie. @react-native-community/slider.

ferrannp commented 5 years ago

@cpojer I can take ViewPagerAndroid. I think better moving it to a community repo (if you can create the repo for me, thx 😄) than just removing it because other packages around have implemented this behaviour on JS for iOS and they relay on the native one for Android.

jainkuniya commented 5 years ago

Hey @cpojer I would like to help by merging and moving Picker and PickerIos. :)

cpojer commented 5 years ago

@ferrannp created https://github.com/react-native-community/react-native-viewpager for you! See the messages above. @jainkuniya thanks! Not exactly sure what that will look like but maybe you can see how to unify them and start sending small PRs to react native.

wellmonge commented 5 years ago

That's awesome! I put your names down next to the items above.

@jdmunro can you send a PR and assign me to it? Then I can take it over and remove FB specific stuff before landing. @Krizzu and @matt-oakes I created https://github.com/react-native-community/react-native-async-storage and https://github.com/react-native-community/react-native-netinfo for you to send PRs against with all the code necessary to make them third-party modules. Ideally in the first step, you'll just take the code from the RN repo and put them in separate repos. In order to ensure it works, we could then link them back into RN as a dependency and remove the original implementation. Further down the line we can actually move it to an optional package. @wellmonge Sounds great! I'm not sure entirely what the work will entail but maybe you can just check out the two modules and see if you can unify them?

Sure! I'll do that and report to you.

dmtrKovalenko commented 5 years ago

Can help with StatusBarIOS and PushNotificationIOS

matt-oakes commented 5 years ago

@cpojer Do you have a preference for the Android package name?

Using NetInfo as an example it is currently com.facebook.react.modules.netinfo. Should we make it standard across all extracted modules with something like com.reactnativecommunity.modules.netinfo?

kdenz commented 5 years ago

Can I help with

vonovak commented 5 years ago

I'll take the checkbox, please.

react-native-bot commented 5 years ago

Thanks for submitting your issue. Can you take another look at your description and make sure the issue template has been filled in its entirety?

👉 Click here if you want to take another look at the Bug Report issue template.

cpojer commented 5 years ago

@dmtrKovalenko put you down for StatusBarIOS, created https://github.com/react-native-community/react-native-statusbar @matt-oakes community in the package name sounds good but if we keep the existing one I'm fine with that too. @kdenz Created https://github.com/react-native-community/react-native-segmented-control for the SegmentedControlIOS @vonovak Created https://github.com/react-native-community/react-native-checkbox for the checkbox repo

Just to summarize the rough steps that we should take for the extractions:

  1. Extract the current version of the module you are working on and all of it's dependencies into a separate git repository, and send a PR to the one that was created for your in RN community. See react-native-webview for an example of how it should work if it contains native code.
  2. Add a deprecation warning to React Native using the warnOnce module that already exists, see react-native-implementation.js for an example.
  3. We'll then close all issues/PRs and direct people to use the newly created projects and repositories instead.
  4. After a release or two we will entirely remove the code from React Native, at which point only the external module will work.
    • Alternatively, we can try an approach where we will remove the code from the RN repository immediately, but add the new community repository as a dependency to React Native and keep the existing APIs working the way they are. I'm unsure whether that will work for modules with native dependencies, though.

Please let me know if you have any questions :)

EvanBacon commented 5 years ago
  • Move ImageStore to a community repo

I think we should deprecate this in favor of any existing FileSystem solution. The core use-case is getting Base64 from an image. It also has no android support.

FonDorn commented 5 years ago

Hey @cpojer! I would help with

Naturalclar commented 5 years ago

I'd like to help out! Could I work on

nissy-dev commented 5 years ago

Hey @cpojer! Could I help with

bartolkaruza commented 5 years ago

@cpojer I'd love to help, sign me up for Libraries/CameraRoll (ImagePickerIOS and CameraRoll components)

The RNTester app doesn't have its own package.json so any components that we remove would have to either be removed from the RNTester app or needs to remain in the core as a dependency. What is the approach for RNTester with regards to this slimmening?

chaitanyadeorukhkar commented 5 years ago

@cpojer I can help with moving Clipboard to a community repo :)

zhaozhiming commented 5 years ago

Could I help with this task? @cpojer

@jainkuniya Maybe we can work together?

jainkuniya commented 5 years ago

@zhaozhiming ya sure, what I was planning is to first merge it in RN repo itself and then move to community repo.

pvinis commented 5 years ago

Interesting. What will happen to the RNTester? I hope we can keep it with all the components.

Ansalibrahim commented 5 years ago

@cpojer I can help with

pvinis commented 5 years ago

Also, it would be very helpful to have some kind of coordinated template, so there is the native code as a lib, an easy way to develop it and contribute.

matt-oakes commented 5 years ago

@pvinis Maybe take a look at this commit from the NetInfo repo I'm working on:

https://github.com/matt-oakes/react-native-netinfo/tree/83e96b30fda1c18f62d27ec0db61db7f56eddc1f

There's no NetInfo code there yet, but it has the Android and iOS parts of the library and an example project which links through without needing a nested package.json.

I'm now planning to move the NetInfo code in and then move the RNTester examples into the example project.

cpojer commented 5 years ago

@EvanBacon sounds good. Do you wanna sign up to add a warning to RN to deprecate ImageStore and recommend a third-party solution?

@matt-oakes has been done a great job with NetInfo already, that's a model to mirror for all the extractions: https://github.com/react-native-community/react-native-netinfo/pull/1

@pvinis as @matt-oakes says every project should have its own examples and testing code. I think once we are all done we can consider creating a single RNTester example that pulls in all the most commonly used extracted modules and brings them together into a single app.

brunolemos commented 5 years ago

VirtualizedList is staying, right? I saw it before in the list but I see it's not anymore.

Trancever commented 5 years ago

Hey @cpojer I can take care of moving ImageEditor to separate repo.

nimish-gupta commented 5 years ago

Hey @cpojer I would love to work on this one

  • Identify all dependencies in package.json that aren't directly used in React Native
pvinis commented 5 years ago

@matt-oakes how are you planning to test or help with developing this lib? we need a project that incorporates the lib, that can be easily updated/disposed-and-recreated or something.

It would be easy this way for others to contribute. It could be an "example" app, but to my mind an "example" app is for showing how to use a lib, where a "dev" app would be where the lib can be developed, tested etc.

Any ideas for that?

cpojer commented 5 years ago

@brunolemos yes it is, sorry my mistake for putting it in there at first.

cpojer commented 5 years ago

@Trancever I created https://github.com/react-native-community/react-native-image-editor for you to send a PR against! @nimish-gupta that's awesome! Can you do the analysis and create a separate issue that discusses the unused dependencies; or otherwise send a pull request with clear explanations on why they can be removed (ie. they cannot be found etc.) @pvinis we are currently discussing whether it makes sense to create a scaffold. Until we have that, basing your work off of the structure in https://github.com/react-native-community/react-native-webview or https://github.com/react-native-community/react-native-netinfo makes the most sense to me.

jainkuniya commented 5 years ago

hi @cpojer for the PickerIOS and Picker project, I am planning to go with following steps:

In the mean time we can move Picker to community repo.

Suggestions?

cpojer commented 5 years ago

@jainkuniya I think the idea is good but keep in mind that Picker uses PickerIOS under the hood. I think it would be best if we could get rid of PickerAndroid and PickerIOS and instead only expose Picker, what do you think? A lot of other components already work this way.

matt-oakes commented 5 years ago

To give people an idea of the process I went through to move the NetInfo code:

1) Used create-react-native-library to generate the scaffolding: npx react-native-create-library --platforms ios,android --package-identifier com.reactnativecommunity.netinfo --prefix RNC --license MIT netinfo 2) Created an example project by running react-native init NetInfoExample in the root of the new library project. I then renamed the created folder to just example. 3) Removed the example/package.json and moved the dependencies and scripts into the root package.json. I also moved some of the other generated files like babel.config.js into the root of the project. 4) Updated the references to React Native libraries in the examples Android gradle files and the Xcode project. Doing a find and replace for ../node_modules/react-native and replacing it with ../../node_modules/react-native was enough. 5) Updated the path to the main module name in MainApplication.java and AppDelegate.m from index to example/index. 6) Added the babel-plugin-module-resolver modules and configured it like this in babel.config.js. This allows you to import the library code in the same way as a user would. 7) Manually linked the library project with the example one. This is very similar to how you would usually do it, but the path on Android in settings.gradle will just be ../../android (like this). 8) I then moved the native code files, renaming them with an RNC (React Native Community) prefix instead of the old RCT. I placed the Javascript code in js and changed the index path in package.json. 9) I then moved the examples from RNTester into the example project and tidied up the code a bit. Feel free to grab the example/index.js file as a way to contain the examples you copy over from RNTester. It's just a lightweight wrapper like there was in RNTester originally. 10) I did tidy up the project a little bit to make it match how react-native-webview is set up. The main changes were around the Android gradle files.

Hopefully, that helps people :)

matt-oakes commented 5 years ago

@pvinis I think there is a lot of crossover between showing people how to use the library and helping with development, especially when the surface area is small like with NetInfo. The example in the project pretty much fulfils both purposes at the same time.

For automated testing, I've not looked into it fully yet, however, I have previously used Jet (based on top of Detox and used by react-native-firebase) to do end-to-end testing with react-native-location.

pvinis commented 5 years ago

Awesome. I did the same process a few days ago when trying to extract some app functionality to a lib. I didn't do the package.json deletion and a couple of other small steps. I will try and check everything you did and I did, and see if there are still unclear things.

Thanks for the details. :)

jdmunro commented 5 years ago

@cpojer SnapshotViewIOS seems also to be used internally for some iOS integration tests. It's only available if you link against the RCTTest native module. Usage is here: https://github.com/facebook/react-native/blob/master/RNTester/js/RNTesterApp.ios.js#L180

Are we just removing SnapshotViewIOS from the public RN export, i.e. it should still be available privately for the test usage?

matt-oakes commented 5 years ago

There was some discussion about how to keep the history of the files which are being imported. I found this guide which was really useful and allowed me to do it for the NetInfo module:

https://stosb.com/blog/retaining-history-when-moving-files-across-repositories-in-git/

As a summary, you first need to find out which files you need to copy over. You then create a script like this:

#!/bin/bash

mkdir -p combined/

# Pipe output to silence "file not found" warnings.
mv ReactAndroid/src/main/java/com/facebook/react/modules/netinfo/NetInfoModule.java combined/ 2>/dev/null
mv Libraries/Network/RCTNetInfo.h combined/ 2>/dev/null
mv Libraries/Network/RCTNetInfo.m combined/ 2>/dev/null
mv Libraries/Network/NetInfo.js combined/ 2>/dev/null

true

You should put this file somewhere outside the repository.

You then need to run these commands:

git fetch origin --unshallow
git checkout -b history
git filter-branch -f --prune-empty --tree-filter ~/treefilter.sh @
git filter-branch --prune-empty -f --subdirectory-filter combined

The first filter-branch command will take a while and will use the script to move all of the files you're interested in into a single folder. The second command should be fairly quick and will move the files from the new folder to the root and then keep only the commits that alter any of the files you want to keep.

You can then end up with a history like this: https://github.com/react-native-community/react-native-netinfo/commits/master

nicholaslee119 commented 5 years ago

hi, @cpojer I would love to work on

Thank you

janicduplessis commented 5 years ago

Note on the fetch polyfill:

Remove the fetch polyfill from the repo and re-use whatwg-fetch directly if possible

We had to fork it because our Blob module is not standard and doesn't automatically release its resources. It should be easier to implement automatic resource cleanup with the new native modules system but until then we should keep the forked polyfill.

Ansalibrahim commented 5 years ago

@cpojer Move "Share" to community repo is currently points another repository which has a rich feature set than the share inside the react-native. So I would like to have a new repository named like react-native-simple-share or something like that.

Please have a look at this branch (I will delete this repo once we get a new community repo)

Jyrno42 commented 5 years ago

Note on the fetch polyfill:

Remove the fetch polyfill from the repo and re-use whatwg-fetch directly if possible

We had to fork it because our Blob module is not standard and doesn't automatically release its resources. It should be easier to implement automatic resource cleanup with the new native modules system but until then we should keep the forked polyfill.

Since I need AbortController.Signal support I was looking into doing an update to the forked polyfill. Would that fit with the future of the fetch polyfill inside core?

rafaellincoln commented 5 years ago

@cpojer I would like to work on PushNotificationIOS.

dratwas commented 5 years ago

@cpojer i could help with

Thanks!

cpojer commented 5 years ago

@nicholaslee119 Created https://github.com/react-native-community/react-native-progress-view for you. Check the comments above on how to make progress. @Ansalibrahim Good point. Created https://github.com/react-native-community/react-native-simple-share for you. Please send a PR there! @rafaellincoln Created https://github.com/react-native-community/react-native-push-notification-ios for you to work on. @dratwas @Trancever is already on it, please work with him on the repo that was created for it. @Jyrno42 Could we upgrade to a third-party polyfill that supports all the stuff we need?