I’ve been developing a mobile app with Ionic 2/Angular 2/Cordova/TypeScript, and given how many moving parts there are in there, and that Ionic 2 and Angular 2 were still beta software when I started—and that I was completely new to all of the technologies when I started—it’s gone relatively well.
However, it’s not a totally smooth development experience, and there are lots of little annoyances which occasionally turn it from pleasant to hideously frustrating.
Because much of the software stack is still beta-quality and sometimes lacking in documentation, that abstraction (of a smooth, high-level development environment) is currently a leaky one. I’m constantly smacking my head on sticky-out-bits that are not supposed to be there. Or, to choose a different metaphor: constantly having bits of leaky abstractions drip on me.
Since ease-of-development seems to be one of their key goals, I imagine that this will gradually get better. I hope so anyway.
My main issues with the framework are:
- Repeatability and reliability of the build process: quite often you need to go into the filesystem and delete some directories and start again in order to get a clean build. Ideally you should be able to check out an Ionic project, or change branches, and run the build command and have it reliably build and run the project, no matter the state of the working tree. On some platforms (Mac OS, the one I’m using), you can’t build and deploy straight from the command-line.
- Ease of debugging: step-by-step debugging on iOS is not supported and stack traces produced by the running software are pretty much useless. This slows you down as a developer. Compounded by:
- Compilation is excruciatingly slow: so edit-compile-test cycles are woeful.
- Native modules are clunky: Native modules let you access non-JS functionality on mobile platforms, but managing them is a manual process, and once you’ve added some plugins, you can’t really test your app in the browser again.
- Lack of/scattered documentation: Ionic itself is quite well documented, but it depends on other, less-well-documented systems. And it’s easy to end up requiring a bleading-edge component with next-to-no documentation.
These issues are all fixable, but they’re all quite painful. I estimate that they’ve cost me 25% of my development time so far. If they could all be addressed, Ionic would be an excellent choice for developing a large class of mobile apps.
As it is, I’m already wistfully eyeing up ReactNative…
Repeatability and reliability of the build process
So there are a couple of issues here: the build process is awkward, the build process is unreliable; and it’s not transparent.
Too many manual steps
You can’t build your app with a single command. There is a command,
ionic build, but you need to restore packages/native modules/platform-specific configuration before running it, and (in the case of iOS development), build and launch the app in Xcode afterwards.
Since packages are managed with npm, the build is not repeatable from scratch. (The developer could probably fix that by moving to Yarn.)
The (wholly achievable) ideal should be: I check out an Ionic project from source code (or switch branches in an existing project), run a single command (
ionic run iOS), and it builds the executable with the correct NPM modules and Cordova plugins, signs it using Xcode if necessary and deploys to the device.
This might require a bit of (once-per-project) configuration of signing keys and provisioning profiles and things, but the principle stands.
As it is, if you install a Cordova plugin, there’s no (obvious) way of removing it again without manually deleting some directories, or removing-and-adding the target platform.
Build targets should be part of the configuration
If you add target platforms (with
ionic platform add …), this isn’t persisted in any build or configuration files. Or, conversely, doing
ionic build platform-name doesn’t automatically create the platform build directories.
There’s a command
ionic platform prepare, and I’m not sure exactly what that does… though I suspect that whatever it is, it should be part of the automatic build process rather than requiring a manual step.
Sometimes the build process fails with a non-obvious error, which can only be cured by deleting the
www build target and building again. Maybe just a bug. But more robustness and predictability would make development less frustrating.
What I mean by ‘non-transparent’ is that you can set up a new project with
ionic start, and that’s lovely, and add a new platform to compile for, but:
- it’s far from clear what files should go into source control, and which should be ignored. (Solutions: better documentation, and put transient files in a separate ‘build’ directory.)
- upgrading to a new version of Ionic 2, it’s not clear how to get all the correct new versions
- if something breaks, or you want to do something unusual, it’s not clear how to fix it.
This is a documentation issue mainly. Since the build process is built on top of WebPack, TypeScript and loads of other projects, what needs to be documented is what Ionic’s build process is made from, and where to go for more information. Googling for error messages is time-consuming and unreliable.
And all the error messages should be explicit about what is wrong and how to fix it.
It’s also an issue of abstraction leakiness. If the build process was reliable and predictable and the developer could build whole Ionic app without ever having to lift the hood and tinker, this would be much less of an issue (or at least an entirely orthogonal issue).
Ease of debugging
This boils down to two or 3 issues:
printfdebugging is possible, but with slow compile-run-debug cycles (see below),
printfdebugging is very, very slow.
- Step-by-step debugging using Visual Studio Code would be wonderful.
- Console logs: I should be able to launch the app from the command-line and have the app’s
console.logoutput show up in the command-line console. This works when running the app in the browser, but not when running on the device.
Compilation is excruciatingly slow
It is. Live recompilation works quite well when running in the browser, but doesn’t work when running in the device.
Native plugins are clunky
Native plugins live in their own directory, separate from node_modules (but require node modules to work properly). Their installation isn’t tied to source control (unless you install the plugin with
--save). What should happen is that you install a node module for a plugin, and the plugin becomes part of the built app. You remove the module and the plugin is removed.
The other issue is that once you install a few native modules, you can no longer run the app in the browser… That’s partially unavoidable: if you don’t have SQLite available, there code needs to be written to work around it. However, the Status-Bar plugin, or Keyboard plugin could be written such that when running in the browser the plugin API still exists and just does nothing.
Ideally there should be an official mechanism for writing alternate code for when a plugin is not available. The Dependency Injection framework could be surfaced to allow different implementations of various modules when running in different environments.
For example, if my app uses the camera or the photo library, this could fall back on the browser to letting the user choose a local image file.
Lack of/scattered documentation
The Ionic documentation itself is pretty good—though it could benefit from being autogenerated from the source. The API documentation is not complete, and during the beta period was not always up to date with the available API.
The documentation for built-in components and native modules is pretty good—but would be wonderful to see examples of bigger and more complex use of the framework. Because the issues always arise when you try to do something which is slightly outside the simple examples.
It would be great to have some documentation explaining Ionic’s relationship with Angular, WebPack, RxJS and the various other foundational technologies.
Ionic 2 has great promise, and if you know what all the bits are doing under the hood, it can be very productive.
However, if you’re new to the platform, going even slightly off-piste can lead to hours of frustrating trouble-shooting.