naomi
naomi

Reputation: 2643

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?

Upvotes: 5

Views: 2211

Answers (3)

Sundar
Sundar

Reputation: 41

Here is medium blog on this topic https://medium.com/@benorama/hybrid-mobile-apps-sharing-logic-between-angular2-and-ionic2-apps-7c32145b90d5

Github link for a sample project https://github.com/benorama/ngrx-demo-apps

Hope this helps..

Upvotes: 1

Picci
Picci

Reputation: 17762

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

Upvotes: 8

Chrillewoodz
Chrillewoodz

Reputation: 28328

I've also wondered how to do this and I came up with a pretty clever solution (I'm using NativeScript instead of Ionic).

What you want to do is have two dev environments while sharing the business logic of the application (with slight variations in terms of imports etc). While the templates and perhaps some styling is different.

One way you could achieve this is by using the NativeScript CLI environment, and then implement your own webpack solution in the same project that the web application will be developed with. Using the Angular CLI with the NativeScript one wouldn't really work all that great because they don't have the same project structure.

Then I would set two environment variables, native and web. Then I use these two in my typescript files to decide what to import and what code to use. If you only need small tweaks in a file you could use it with simple if statements, but if you need a whole component to change you could switch the entire file by checking these environment variables.

Regarding the templates and styles you could do something like name.component.native.html and name.component.web.html and use the one that matches your environment variable. Same goes for the style files.

Depending on how big your project is I think this is a pretty manageable way of sharing code easily without having to manage 2 projects separately.

I'm not saying this is the correct way of doing it, but it's a way and I think it could work brilliantly if done correctly.

Hope this is helpful in some way.

Upvotes: 0

Related Questions