Ionic Monorepos with NX

Today I am writing about Ionic and how to use it with NX. As I explained in previous posts Ionic enables you to write Angular code that can be used as the base for Android/iOS applications. So it enables you to write code that can be shared across all plattforms, which is a great opportunity. Together we will create a Nx monorepo which contains an Ionic application and can be extended very easily. You can find the code in my Github repo.

Why do we need Monorepos for creating this type of application? For many applications you not only need a frontend but also some backend functionality. In some businesses you might also have severall applications created in a project, something like a mobile app, a administrative application and so on. Most of the time you share functionality across both applications. To face that challange there are different approaches, one are node libraries which are shared across both applications. Another one would be to use Microfrontends and bundleling those frontends to two different applications. The third option is to create monorepos. All three approaches have pros and cons, however, if you have one or two frontend applications and maybe a Javascript backend application monorepos might be a good option for you. In general a monorepo is a project, that contains different projects and some shared functionality. NX is the framework that is used most the time in Angular projects. NX also creates configs for TypeScript, EsLint, Webpack and so on. So it provides a base to create extendable and maintainable applications that are consistent.

Basic setup

To start you need to have a running Node enviroment with an installed npx version. You can install npx by using npm i npx

Nx has in general some plugins that are summarized by Nxtend. Those are built to create specific type of applications in a NX enviroment. For instance, there is the @nxtend/ionic-angular plugin or a plugin for creating Nest backend applications.

To start of our application we need to create an empty nx workspace. That is done using the following command:

npx create-nx-workspace my-org --preset=empty

After typing in that command you might get asked if you want to use nx cloud. For this post I did not use that type of configuration. After the command is completed you will see an empty workspace that was created for you. This workspace does not contain of any application yet. If you have a short look into the created project you will see that the structure is a little bit different from normal Angular applications. Of course, you have a package.json but also there is no src directory. There is however an apps folder as well as a libs folder. The apps folder will later contain our applications and the libs folder can be used to create shared libraries. Also you might notice the jest.config files, that is because Nx is using Jest as the default test runner for unit tests.

Generating applications

I will create an Ionic application that uses Capacitor here. First of all we need to install the Nxtend Ionic Angular dependency and initialize it:

npm install --save-dev @nxtend/ionic-angular

In order to be able to use nx as a npm command I extend the package.json with the following script:

....
"scripts": {
  ....
  "nx": "nx"
},
....


npm run nx generate @nxtend/ionic-angular:init

After executing these two commands you can generate the new application:

npm run nx generate @nxtend/ionic-angular:app demo-app

Great! Now we have created our Ionic application in our Nx workspace. If you have a look into the code you will see that there is now a new folder in the apps which contains the demo-app. Also nx has created an E2E testing project for us that contains everything to get started with E2E testing with Cypress, great, isn’t it?

Now let’s have a look into the created application. Type in the following command to start a debug version of the app:

npm run nx serve my-app

It is possible that you see the following error after typing in that command:

Property 'name' has no initializer and is not definitely assigned in the constructor.

This is because of the default tsconfig which forces you to initialize all variables. To get rid of that error you need to go to the tsconfig.base.json and add that line to the compiler options:

"strictPropertyInitialization": false

After running the nx serve command again the compilation should work and you can checkout your awesome application.

Creating the Android app

Next, we want to create the Android app out of the code that we have so far. For doing that we need to build the app and than add the android plattform. For building the app you can call nx build demo-app. Also it is a good idea to extend the package.json with a script that is doing that in the future for us:

"scripts": {
  ...
  "build:demo": "nx build demo-app",
  ...
},

To add the android project you need to run the following command:

npm run nx run demo-app:add:android

This will create an android folder within the demo-app. This is used to create the APK. If you want to create iOS apps you can run the command

npm run nx run demo-app:add:ios

To open the app you need to call npm run nx run demo-app:open:android. Here I also suggest to add that script to package.json:

"name": "ionic-workspace",
"version": "0.0.0",
"license": "MIT",
"scripts": {
  ...
  "open:demo:android": "nx run demo-app:open:android",
  ...
},

If the code is changed you need to copy the new code to the android app. That is done using the command npm run nx run demo-app:copy:android. I also add that script to the package.json:

"scripts": {
  ...
  "copy:demo:android": "nx run demo-app:copy:android",
  ...
},

Creating shared libs

In the introduction I already explained that nx provides a possibility to create shared libraries that may contain shared functionality or model classes shared in different projects. To create the lib you simply need to type in the following command: npm run nx generate @nrwl/angular:library shared-lib

This command will setup everything so that you can simply use that lib. As already explained, libraries are created in the libs folder. After you create some class you will see the true magic of Nx, there is no need to recompile the library or add some package to a npm repository. You can simply import the created class if it is added to the index.ts of the lib:

import { ExampleSharedClass} from '@ionic-workspace/shared-lib';

Conclusion

As you see from that blog post, it is really simple to use Nx for Ionic Angular applications. Nx will bring you a scalable application with very useful preconfigured parts. That is why I would suggest using Nx for your next project if it fits to your requirements.

What do you think about using Ionic with Nx? Have you used Nx in the past? Was it useful to you?

My opinion mobile app development

Finally back on spot! Today I would like to talk about mobile app development. An exiting topic, isn’t it? But when it comes to choosing a particular technology it gets a bit difficult. There are million ways out there to create that awesome flashlight app for mobiles that will make you rich. You could create a native app, you could create web apps, your could go some hybrid way, so what is the best option? Simple answer? There isn’t one. Or as consultants prefer, “it depends”.

I was also at the point of choosing a technology for an application. And as I had no idea what I was doing I needed to more or less test all the ways that are available. That is why I would like to share my opinion, of course, there are plenty of tutorials for different technologies. But when it comes to choosing a specific technology answers get more rare.

Ok, lets start. If you think of mobile app development the first thing that might come to your mind is to check out the development pages of the creators of the mobile operating system you would like to support. I think that is a very good idea and as both, Apple and Google, explaining basics of their systems you are getting a basic understanding on how those platforms work. Also you get an idea on the design guidelines that applications for those platforms need to meet. Actually that is a very important point if you create apps, your app should follow the usability guidelines so that users are not getting confused. Especially when you focus on Apple apps you need to follow those principles, if not your app will not be able to get into the app store.

What the platforms of Google and Apple are also describing is how to create applications for their operating system. This is called “native app” development and means that you are creating an app just for one operating system. In some cases that is totally fine, maybe you want to address only one platform. But if you want to support both systems that gets a bit complicated. As you need different programming languages (Kotlin or Java for Android, Swift for iOS) it is nearly impossible to share code between both platforms when you do native app development. That is why often other technologies are used these days which I am going to explain later. However, in some cases two native apps make sence. If you need to create lot of device specifc features it is always a good idea to use the native ways.

Another option is going a complete other ways. The web today offers the possability to use native features in a web page. This powerful technology is called PWAs and such applications behave like native apps even thought they are opened in a browser. Many web pages use such technology already and in many cases this make sence. I used such a way when I created an application for a fair. So in that case the most important thing were the informations and creating native apps for such a thing would be too much work. With a PWA I could use the camera of the mobile phone or to create Push notifications when something was started. With PWAs you are able to share 100 percent of the code between both platforms. One disadvantage of such a way is that users cannot find your application in the app store. At the fair some people immediatly opened the app store when they saw that there is an application. That might be a problem. Also it is more difficult to make users use the app often, for PWAs it is essential that everything works as users expect, if that is not the case they would go to another site and will never come back to your app. If applications are installed they payed at least the effort on installing the app, so getting to a new app is more difficult. Also it is still not possible to access all native features as well as games could be difficult to realise in such a way.

A good way in the middle is creating cross plattform applications using the Apache Cordova framework. One framework that uses Cordova as well as Angular is Ionic. I like to use Ionic for many reasons. It provides many components that mobile apps need, it has a fantastic documentation and it can be used to create applications for all platforms (you can create native apps, windows store apps and web apps with just one framework). What that platform does is creating a native application that opens a browser were your content is displayed. The user just sees the native-like application. By using Cordova you are able to access device specific features. By using a CSS all the components really look like native components. I would choose cross plattform development using Ionic when it comes to business applications were you need to display and enter data in different masks. The only thing I do not like is that most of the Ionic components look like iOS components, in Android those should have a bit more adoption. But you can have native Android experience by adding another CSS framework like Material Design.

As I described above, with cross-plattform-application development in Ionic you are creating an application that runs in a web browser that the user does not see. That brings some disadvantages. On the one hand, you can have difficulties when trying to create customized native components. On the other hand you might get performance issues on elder devices. But the way of sharing a single code base in different applications is something that is not such a bad idea as nobody of us likes to create the same code over and over again. Platforms like NativeScript, ReactNative or Xamarin try to solve that problem. What those platforms do is creating native code from your code that is written in a shareable way. Which framework you are choosing totally depends on which framework you like. NativeScript supports Angular, ReactNative supports React, if you are a C# guy, Xamarin might be an option for you. I have used Xamarin in the past and I had good experience in using that platform. As you are using C# you can access many features of the .Net framework that are very useful in some cases. One problem that I often had with such frameworks is the time to render the code so that it can be tested. As I described, your code is translated into native code. And this takes some seconds that can be pretty long for a web developer like me that is used to short compiling time. However, that part gets better and better and Ionic has the same problem when it comes to testing device specific features.

Last but not least I would like to write some lines about Flutter. I need to say that I didn’t create whole applications using that framework but I played a little bit with it last time. And in my mind that way of creating applications definitly deserves attention. The idea behind Flutter is to create apps for all plattforms using one programming language (Dart). It provides many so called widgets, that you can see as different kind of functionalities. Flutter is the SDK that provides native applications, so you get all different advantages of native apps without loosing the advantage of a single code base. For me learning Dart was very easy as I have experience in C# and Java. Not only this framework is easy to use by developers, it is also easy to be used by not expererienced developers as the platform provides many different functionalities already. Those are called widgets and provide things like form controls, buttons, accessability, … So everything you need with an app. As this way of creating apps is pretty young but very promising I think it will get more attention and therefore I am going to have a deeper look too.

To summarize, if you are creating mobile apps you have to make a decision on a specific way by looking on your requirements. Not every framework is correct for a specific case. I often use Ionic or PWAs as I am a web developer but in many cases native apps are worth a thought. To share a codebase with a native app you can use frameworks like Xamarin but not always that way is the most performant way. And last but not least you need to have a look on the different trends on the market, like Flutter.

What framework do you like to use? Are you a native app developer or do you prefer cross platform development?