What is Code Sharing?
Code sharing is the concept of reusing certain components between multiple applications. This could be logic, assets, structure or even just source code in general. There are various forms for code sharing, but I am going to focus on the single repository pattern. I will explain this pattern, and the reasons and times when to use it. Additionally I will write about how to use it for sharing between web and mobile applications.
Why should you use a single repository?
This approach has almost the same benefits as any Monorepo – a strategy where the source code of many projects is stored in the same repository. This pattern existed for a while but gained in popularity after its adoption by some of the most famous tech giants: Microsoft, Google, Facebook, Uber, Airbnb, Twitter and many more.
Using this strategy makes it easier to reuse code by abstracting similar functionalities across projects into shared libraries that can be used by any application with the same requirements. Due to the presence in the same directory, other teams are more likely to learn of its existence before building their own toolkit, which saves times and money.
The usage of shared libraries simplifies the process of maintaining the projects aligned. This is achieved through sharing business logic, structure, corporate branding and many other things. When a change happens on one of these parts, maybe because of a bugfix, all projects and applications will profit from this change and none is left behind. When using multiple repositories, the change must be introduced in every repository separately, which is very time consuming.
Another positive aspect of a shared repository is the flexible code ownership: When in need, the teams can support each other to absorb high priority bugfix sprints or a lack of team members. It also favours collaboration across teams.
How can this be applied?
Sharing code between Android and iOS
One possible framework to achieve this is NativeScript, an open source framework for developing mobile applications using JavaScript. This is achieved by shipping a JavaScript virtual machine that interprets and executes JavaScript code at runtime. These calls will then be translated to the platform-specific API calls by a bridge module. This is also responsible for returning the results to the caller. This results into native API calls with a bit of bridge-overhead but this is still faster than running the application in a full web view.
The only difference to web development with JavaScript is that we do not have access to any DOM or browser functionality. Otherwise all existing JavaScript libraries still work, e.g. CocoaPods, Android Arsenal, NPM.
Plug-in integration
Since it is only JavaScript running in the application you can use your favourite component framework like Vue.js and Angular, which are both supported with a plugin. In this article I will focus on the Vue.js part, but the Angular version is just as self-explanatory.
To integrate this plugin in your existing project or create a new one that is ready to go, it is recommended to use the Vue CLI 3 plugin NativeScript-Vue.
Asset and component sharing
Since the application is constructed as a single project, we can place these in a special folder in the source directory and access them easily on every platform in our application.
Modular build using Webpack
Webpack will look for the respective components based on the platform you select. If you select to serve the application to an Android device it will look for component files that are named like *.native. (for Android and iOS) or *.android.. All files that are named like *.ios. or **.vue will be ignored. However, if the project space is configured for native only development **.vue will also work.
One Step further
While sharing the code with Android and iOS is still a major improvement over the previous workflows, it still can be improved by sharing the code with the web application. This is achieved by using the library NativeScript-Vue-Web.
This allows us to develop web applications using NativeScript-Vue-like syntax. The exact same templates generated by this approach can be used for Web, Android and iOS components, thus further reducing the amount of code and maintenance effort.
Alternatives
Xamarin.Forms
On the first glance these two could be doing the same thing for different languages, but they have a very different approach: Xamarin will compile native applications for each platform and deploy these. When using NativeScript however, your written JavaScript code will land on the device and interpreted there by the JavaScript virtual machine and be bridged to the native APIs.
Progressive Web Apps (PWAs)
PWAs are limited since they essentially run in a web browser and are not running natively. This influences performance but also restricts the access to hardware and to native libraries.
Cordova
These apps are pretty like PWAs and bridge web and fully native applications. This results in the same limitations.
Summary
Using the NativeScript-Vue-Web library allows us to write a single Vue.js application that can run as a web or native mobile application on both Android and iOS. This can allow you to share up to 100% of the code, but also supports having custom components for specific target platforms.
It is an excellent library if your team is proficient in Vue.js and has to support multiple mobile platforms.