-
Notifications
You must be signed in to change notification settings - Fork 34
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
RFC: Upgrade the app UI to a more modern javascript framework #857
Comments
Yayyy! I don't know too much technical details on these mobile app frameworks. So my only vote is that we choose a framework that is widely used, has a strong adoption rate, and not going to be obsoleted any time soon. This would make hiring someone to work on it less challenging which is unlike the current pairng of Ionic and PhoneGap (?) that we chose. |
@asiripanich ionic and cordova (phonegap was closed source and is EOL, cordova is open source and is still maintained) I suspect that the biggest challenge that you are facing is with the ionic1/angularJS UI (other than @ericafenyo nobody has ever contributed native code). AngularJS is also EOL |
To narrow down our choices, I think the next major question is whether we want A) a truly native app, or if we're ok with B) a web solution packaged as a native app. For (A) we'd be looking at React Native (unless anyone is particularly enthusiastic about Flutter)
For (B), we have countless options.
|
We want to keep the hype to let the community interested in working on the project. We need to be able to refactor the mobile app every 5 years to stay in the flow. We have less then 10 people so we need to find the balance between a long term support community and enough people to work on the project. |
For reference, the 2022 stackoverflow survey, with the most "hype" frameworks https://survey.stackoverflow.co/2022/#section-most-loved-dreaded-and-wanted-web-frameworks-and-technologies (For our sanity, we should look at the most loved techs, not the most dreaded ones, where we would find both angular.js and cordova 😆 ) |
@TTalex that does seem to argue for React, but React webapp or React Native? Note also that flutter currently seems to be higher on the hype scale than React Native. |
From the table that @lgharib created, a solution that might check all the boxes might be ReactJS (Web Components) on a React Native base. This would have the following advantages:
This will also support @TTalex's comment that there are likely to be lots of UI contributions and few native code contributions, so it might be better to keep the UI and the native code separate instead of integrated. It looks from some light searching on the internet that this might be possible Does anybody with more experience with React Native (e.g. @lgharib) have thoughts on the feasibility of this approach? This will also allow us to use the following migration path:
= get reactJS over react native The only high-level con that I can see is that React Native is not part of the Apache ecosystem, so it is not clear what will happen if/when Facebook pulls funding for it. Or maybe that this is the worst of both possible worlds instead of the best 😄 |
There is also this option https://necolas.github.io/react-native-web/ Final thought, we can create custom react native components as well. And honestly most of the complexity in e-mission/OpenPATH is in the javascript, not in the rendering. |
Interesting idea, but I can't find evidence of anyone who is actually doing this. I think the main appeal of React Native, to most people, is its native rendering. We already have the existing Cordova plugins, which Capacitor would probably be backwards-compatible with. Capacitor also has its own library of native plugins and plugins from the community. |
My 3 cents:
|
Since the high-level seems to have equally balanced pros and cons, at NREL, we are actually diving a bit deeper into a few alternatives. The two alternatives are:
|
Wrt approach (1):
The big question that I have is whether they can make calls from the javascript layer to the native layer with this approach (aka re-implement cordova :) @TTalex do you know the answer? @JGreenlee and I will poke around the codebase as well, but presumably somebody at Cozy such as @paultranvan can give us a definitive answer as well. |
Regarding approach (2), I did a little bit of experimentation with WebComponents to see if it would be possible to gradually migrate components in-place. This approach is possible, but there are some caveats. One of the things I realized is that the version of AngularJS we use (1.5) is not the best for WC interoperability. The good news is that I found a few tools that can make this more seamless. ng-custom-element will allow us to bind angular scope variables to the properties of our custom web components directly in the HTML. Without this, the process would be a huge headache. If we use WebComponents, I'd also like to use lit, which is a lightweight set of helper functions and a declarative template system, that sits on top of WC to make them a lot more useful. This way, its are features more congruent to AngularJS (and whatever framework we convert to later) and passing data back and forth is not so complicated. Using those tools, I converted a couple components to test. I made a Once I found the right methodology, it worked pretty well. I didn't convert them all the way, but it was just an experiment and a proof of concept. We do have this as an option, and over the next few months we could gradually refactor into WC until we no longer depend on AngularJS and Ionic v1. Then we are free to use WebComponents in whatever framework we choose. |
I poked around about this, and it looks like it is possible, but might be a bit tricky.
|
This kind of bridge is uncharted territory for me. So I can't really help. However, the app does have a kind of labelling support, but I believe it's missing the connection to the openpath server. Updated labels are not sent back to the server, they are stored somewhere else. By the way, the app also has the beginnings of an automatic labelling system, it finds similar trips and applies the user input to all of them. |
@TTalex as you know, we already built an automatic labeling system and it has been in production for a while. We also wrote a paper on it - it is a bit non-trivial to get super-good accuracy. We also just expanded the labeling system to support more complex surveys and changed the display mechanism to be more performant. I would really like to make sure that we are coordinating with Cozy, so that we don't waste our (limited) time implementing the same functionality over and over. The whole premise of an open source community is that the whole is greater than the sum of the parts ( |
FYI, AirBnB tried react native and went back to pure native. Interesting post, but I am not sure if it is very relevant to our situation since it looked like they already had native apps and their concern was that they had to now support three platforms. |
To recap the approach that was put forth today, we can migrate in three steps:
However, I thought about this a little bit afterwards. It is possible to do a soft migration from AngularJS directly to ReactJS. This seems relatively common. (Babbel, Awesense). |
The second link from above implements its own solution to allow the use of ReactJS components inside AngularJS. Other guides recommend react2angular. |
As I said during the meeting, the current community membership seems to lead us inexorably towards react. I do want to point out that we can create web components using reactJS now That uses a wrapper library to wrap the reactJS component into a webcomponent without changing the react component code.
I would really like to see if there is a way to expose the same component functionality as react native and web component. |
I have to try this out, but it looks like react-native-for-web does exactly this "expose the same component functionality as react native and web component." The only difference is that we had assumed that we would first write web components and then figure out a way to use them in react native. With react native web, we write everything in react native (so the JSX has View, Image... but then use the framework to use the react native components directly as web components in reactJS.
This seems like it would allow us to reuse components for native and web and give us a non-horrendous migration path to other web frameworks in the future (potentially using react-to-webcomponent) if we wanted to. |
🎉 I have good news! (with some caveats)It looks like, at least from a UI standpoint, the migration is not going to be as hard as we may have thought. I experimented with several approaches that would allow a soft migration to ReactJS and React Native. See the following:
Some things to note:
The complicationsAngularJS to React Native is a significant jump, and I somewhat doubt that anyone has done this exact process before. The good news is that 1) after wrangling with it for hours, I now understand things much clearer, so maybe the initial headache is out of the way and 2) we can break the process into steps so it's not all too much all at once. I think we can prevent a lot of frustration by just having a solid plan for the prep work that we will do before we introduce React. Suggested prep / Refactoring before migration
Overall suggested planGiven these findings, I created a roadmap of what specific steps I think will be necessary for this plan to work. |
Good job @JGreenlee ! Very interesting read. That looks like a sound plan to me :) |
Agreed. Great summary, @JGreenlee! I am glad that we were able to fold in React Native for Web so that we have both portability and a modern toolchain. I can see that this is a lot of work, but it honestly seems fairly doable once we have the initial templates set up. It seems like just using @lgharib @AlirezaRa94 @ericafenyo any thoughts on this migration plan? |
One more task for prep/refactor in AngularJS is to merge the Are we the only ones using a multi-tenant architecture?
|
@JGreenlee another consideration is the enekto survey code. Some potential options for dealing with the surveys are:
|
If there's a react native alternative that'd be great but I don't know of one. I was envisioning that we would just keep Enketo and wrap the surveys in a webview. If we do keep Enketo I think we should try to get even with enketo-core so that we can benefit from upstream improvements. |
Moment is another library we might consider swapping out during the rewrite. Moment is not deprecated, but they consider it a legacy project and recommend modern alternatives. I thought we might be able to use no library and only |
There are at least 2 web-based libraries that we want to keep using, but use non-native (HTML) rendering: Leaflet and Enketo. @shankari Before I go much further, I wanted to discuss how we plan to do this, because I think it's going to get messy. We can't put raw HTML in React Native Web and I thought it would be simple enough to just wrap these in a WebView. Although there is a way to do this, it's somewhat absurd: I actually burnt several hours trying to wrap a Leaflet map in So yes, wrapping things in For maps, we do have the alternate option to use For surveys, I haven't really seen any options for ODK-compliant forms in the RN ecosystem. Not really sure where we go from here. Whatever we do, I think it's going to be a "lesser of two evils" kind of decision. |
So for enketo, I think that a webview would be fine, since we always launch it as a full-screen view anyway. Either in a popup or in the ion-view directly. Leaflet is trickier and I'd forgotten about it because I got so used to using it everywhere. I do think we want to avoid Google Maps because (i) we want to avoid changing our implementation and (ii) as an open source project, it is better to use open source components and not introduce any requirements for closed source APIs if possible. Having said all that, I am a bit confused.
But first, I want to see if |
correction: wrt
It's been a while since I've written a native UI (I think we moved to hybrid ~ 2015), and things have certainly changed since then. It looks like an API key is now required even just to show a google map in Android. This is not a requirement of the plugin but of the underlying google library - e.g. Ah but then we could just use I am not 100% sure if we can have multiple of those components on the screen at the same time (as we would need for the label screen); we would need to experiment with it to find out. |
Good news! As it turns out, React Native Web is more flexible than I thought - sorry for raising false alarm. I didn't think that putting raw HTML inside React Native Web was going to work, but it does as long it's ultimately being rendered as HTML. This wouldn't work with native rendering directly, but we won't need to do that until later. As long as we're operating over Cordova, we can use HTML alongside (and within) React Native Web components. I got this working with Leaflet, so we can just work with that for now. The same should work for Enketo. When it comes time to switch to Expo, we will need to wrap these in |
--For the record:--
This is how
I am not sure if we can use 'pure' ReactJS libraries right now. It might work, but only temporarily. We should try to implement as much as possible with React Native Web libraries, that way it's guaranteed to work with Expo web later. |
Options:
Ideally, we want to be as forward compatible as possible since web frameworks change often and we don't have a large dedicated team to work on forward migrations every two years.
One option that we are seriously considering is to convert all of the main UI components into standard web components. This will allow us to migrate at the top level - e.g. the glue framework - quickly and then slowly migrate the individual web components over time, one every month.
I will also note that one of the requests that comes up periodically is to support a web version (sort of like WhatsApp vs. WhatsApp Web) so that people can explore their trips on a bigger screen. This is very low priority right now but we can keep it in mind for later, especially if we want to support more complex visualizations of the collected data.
@TTalex @paulvantran @asiripanich @larbigharib @ericafenyo in case you have thoughts. We can discuss further at the monthly meeting. We hope to make the switch over the summer.
The text was updated successfully, but these errors were encountered: