Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share code for hybrid mobile app and desktop web app

I want to build a brand new app that should be deployed both as a hybrid mobile app and a desktop web app.

Mostly the logic and the user interface are very similar for both apps. Except for some differences:

  1. Screen size optimization for mobile (e.g. hidden side menus in mobile vs expanded ones in desktop)
  2. Touch gestures (3DTouch) in mobile vs hover functionalities in desktop
  3. Touch feedback for some elements in mobile
  4. Page navigation in mobile vs routing navigation in desktop

I thought of using angular-material components for desktop, and Ionic components and navigation for mobile as both are built on top of angular.

Of course I aim to share as much code that I can, for the logic but also for UI container components.

So I trying to think of a good way to structure my project while creating separate Angular Modules for the desktop UI, mobile UI, shared UI and logic:

One option is to have one Core Module for both apps, importing the logic and the shared UI modules.Then switch between the specific platform UI module, when building for each platform. In this option the platform specific UI components will have the same selectors and @Inputs, but will differ in their rendered UI.

The second option is to have separate Core Modules for each platform app that will import the logic module and the shared UI components module.

Maybe someone has experience of doing such a thing and can share his thoughts about the best project structure covering all of this?

Or which project structure I've suggested is better?

like image 340
naomi Avatar asked Feb 05 '23 10:02

naomi


1 Answers

From my experience what works is the following

  1. Create 2 separate 'Front End' projects with separate file structures in separate directories, using the specific "command line tools" of the framework (Angular CLI, Ionic CLI, NativeScript CLI).
  2. Create a common project that contain the common modules to be shared by the 'front end' projects
  3. Import from you code repository the shared modules into the 'front end' projects (e.g. under a directory named 'shared') - make sure you keep aligned the front end projects with the same common version of the 'shared' project

The real trick though is to set the boundaries of the 'shared' modules in order to maximize reuse without increasing the complexity of the code (e.g. by having checks of the environment in the 'shared' code - I avoid having environment variables to define if the code runs in Ionic or Angular and take decisions based on that variable).

The rule of thumb for me is that 'Front End' projects define all the Components (i.e. the Components are not shared).

Components have very shallow logic, usually something like the following

  • They define in the constructor the services they use
  • in the ngOnInit() method they subscribe to the Observables of interest returned by services methods - the subscription logic fills the variables that contain the data shown in the view
  • in the ngOnDestroy() they unsubscribe the subscriptions
  • Components define the methods that manage the Front End events - such methods usually invoke methods on the shared services

The right design emerges while coding. What I mean is that once you put in place the basic structure (i.e. the 'Front End' projects and the 'shared' project) you start coding for one Front End (e.g. Angular for the browser). Some decisions are easy to take (e.g. all logic to query back-ends usually is shared). Some other decisions are more tricky, and this is more true the more the logic is close to the Front End surface. As soon as you see that the logic within the Components is getting thick, then you start wondering whether there is something worth sharing because maybe is common also to the other 'Front End' (let's say Ionic). If this is the case, then you refactor, moving code to the 'shared' services.

Remember also to adequately protect 'shared' services with tests.

I hope it helps

like image 103
Picci Avatar answered Feb 11 '23 23:02

Picci