A complete Ionic starter based on Angular CLI, check it out!

Just a quick heads-up for those interested, the latest release of ngX-Rocket starter has now Ionic / Cordova integration on top of Angular CLI:

There is a few non-critical limitations though, that will hopefully be smoothed out over time (if the Ionic team allows me to :wink: )

As for the differences of using this starter with Angular CLI vs the Ionic CLI, here is a quick summary:

  • Follows Angular style guide conventions: naming, structure…
  • Projects are organized by feature modules, allowing better scalability for big projects
  • Automatic cache busting enabled by using hash on CSS/JavaScript filenames (critical for web apps!)
  • Unit tests support with Karma/Jasmine
  • End-to-end tests support with Protractor
  • CSS encapsulation in components
  • Routing with standard Angular Router (route-based selective feature module lazy loading is now possible)

Feedbacks are welcome! :tada:

3 Likes

Interesting!

Have did you manage that with regards to IonicPage? Or did you rip all of that out?
What exactly is different?

What does that mean? Wasn’t this already the case with standard Ionic?


I quote from https://github.com/ngx-rocket/starter-kit/blob/cordova/ionic/docs/coding-guides/ionic.md#limitations-with-ionic-cli

Cannot organize projects by feature modules
What exactly does that mean?

No unit tests support
What about https://github.com/ionic-team/ionic-unit-testing-example?

No selective module lazy loading
What does this mean exactly?

As noted in the limitations @IonicPage annotations are not supported (issues were reported to Ionic team, see https://github.com/ionic-team/ionic-app-scripts/issues/1093, https://github.com/ionic-team/ionic-app-scripts/issues/1091 and https://github.com/ionic-team/ionic/issues/12285), but it is instead replaced by a more “classic” Angular Router approach (quoting from limitations):

  • No @IonicPage deep linking and lazy loading support (tied to Ionic CLI, see this issue). Instead we use the Angular > router which has better predictability, tied to Ionic push navigation.

    In addition, the deep links plugin can still be configured to support mobile deep linking in addition to URL routing.

Nope, CSS encapsulation is completely disabled with Ionic CLI (you can write global style in any component css, eurk!)

You should read Angular Style Guide and NgModule doc to get more details about how and why use features modules, but basically the recommended angular structure cannot be used completely (and is not used at all in Ionic CLI starters) with Ionic CLI, especially because of @IonicPage forced structure under the /pages folder and with 1 module/page.

It’s not supported out-of-the box by Ionic CLI, you have to do the integrate by hand. Besides, the example provided in your have several issues, see this comment of another repo providing example testing integration with Ionic.

With Ionic, you cannot choose to use lazy loading only a specific feature module. Either you use @IonicPage which enable lazy loading for each screen (which is often not desirable in a web context!), either you do not lazy load at all.

With an app organized in feature modules and using Angular Router, it is really easy to add lazy loading only a given screen or feature module, see https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html/

I hope that this answers part of your questions :slight_smile:

So because it is not integrated by default it is not supported?

Are you sure that is true? I can freely choose for each component/page if I want it annotated with @IonicPage and be lazy loaded and not.

I like your project, we talked about it before I think in some Github issues, but I am asking so critical because I really detest it when people base their projects on the work of others and then are not accurate about the differences or advantages. No need to bash anyone.

Haven’t had time to check the whole project out properly but it looks very interesting, I know there are people out there who prefer that Angular best practice type structure.

Just a quick note on lazy loading, you can configure this pretty well by using preloadModules and setting the priority, i.e.:

@IonicPage({
  name: 'my-page',
  priority: 'off'
})

so if you want everything preloaded you can just set the priority accordingly, and anything you only want to lazy load when it is accessed you can set the priority to off.

1 Like

You are right, but this still cause undesired overhead for web apps, as each page becomes a new JS chunk during compilation, causing 1 HTTP request per page for all page modules, even with preload enabled, so it’s still not ideal.

It sounds as though you’re floating Ionic components on top of an Angular project. Is that fair?

I’m not sure sure if that is what your meant, but said differently yes it’s using Ionic just as any other UI library in a conventional Angular project (you can also choose to use Bootstrap in place of Ionic by the way if you want to). The choice was also made to rely on Angular tools (CLI) and to follow recommended Angular’s best practices and conventions instead of Ionic’s.

1 Like

Thanks. What do you see as the benefit of this, then? If I’m just writing a PWA, I don’t need hybrid components. And if I’m writing a hybrid app for handheld devices, the Ionic router is a better fit than the Angular router. It’s interesting from a technical perspective, but I can’t quite wrap my head around the use case yet.

Read again, I never said it was impossible to add unit tests to a Ionic CLI project, just that Ionic CLI does not provides support for it: you have to integrate other tools yourself, configure them and add the scripts to run tests and report coverage yourself (and maintain it). With Angular CLI, you have all of this out-of-the box.

Maybe my phrasing was bad (and I apologize if that’s the case), I just implied that as long you use the @IonicPage annotation (for example to use the automatic deep link generation), lazy loading comes with it whether you want it or not. And even if you can use preloading as @joshmorony noted, it still creates extra JS chunks and requests.

Also, I’m not sure (but I may be wrong on this one!) that mixing @IonicPages components along with "not @IonicPages" components is a recommended approach of the Ionic team, from what I understand from the documentation and provided example projects using it, it’s either all or nothing.
If that’s not the case I will happily correct the documentation.

I was not trying to bash any of the fantastic work of the Ionic team, but merely trying to compare what you may gain from using Angular CLI (not my work by the way :wink:) over Ionic CLI to help people understand the differences. And seeing from the messages from this thread, it seems it’s not clear enough so it’s fair to be critical so it can improved :smile:
(BTW, PR are welcome if your think the doc is not accurate).

Just as a friendly reminder, I clearly understand that the Ionic team have different objectives than the Angular team (first things coming in mind: learning curve, simplicity and for what’s coming next not being tied to Angular at all) so it’s fair that there is differences.
I am merely sharing another vision of what Ionic project can be, more “integrated” in the Angular world.

Some examples:

  • Using the same code base for targeting both a web app and an hybrid mobile app (which is exactly my current main project now, a big enterprise app with more than 120 screens, based on Ionic v1)

  • Making a web app or PWA, the Angular router is better fit in my opinion for purely web perspective (and the Cordova/Hybrid app target is optional in the linked generator)

  • If you’re making an hybrid app only you are right, from the routing perspective the Ionic navigation system is simpler and @IonicPages are definitely a plus.

    But you cannot use Angular conventions, and you have to integrate unit tests and end to end test yourself, and the default Ionic settings (for example the lack of CSS encapsulation) are more lenient, which is not a good thing for enterprise project where quality is the first requirement.

    And as a side note, using the Angular router does not prevent you from using Ionic push/pop navigation system, in fact in the implementation I’ve made both are just glued together so you’re free to choose.

It’s merely an alternative solution that may suit some people more involved in the Angular world, that was initially started to fill a need for the many enterprise projects we had and found no solutions for.

2 Likes

No, it’s certainly possible to mix the approaches and only lazily load certain pages. It does involve some discipline in what arguments you pass to the navigation system, because you pass eagerly loaded pages as class literals, while lazily loaded ones as strings.

1 Like

Ok first, let me say that I think the recommended Angular directory organization makes a lot more sense than what the Ionic generators create. Actually, what I think is happening is that Ionic looked at popular apps like Facebook and Instagram and saw they only had a few pages each, so they envisioned their target user as someone creating apps with maybe 10 pages. In which case, the Angular recommendations are overkill.

But there are people writing much larger apps, and I’d love to tell the Ionic CLI to generate pages and providers for large apps (so a different mode from default small apps). That said, I don’t understand what part of the code base you want to stay the same.

I’ve built a web page with Ionic components, and I’m not doing it again until driftyco makes the components more PWA-friendly. I needed to do a ton of formatting, because a button that goes all the way across the screen looks lousy. I almost had to create two pages for each page, testing the value of platform.is() and then displaying formatting appropriately. Not trying to rain on your parade here. More wondering how/if your work might make my life easier, and I’m not quite on board yet, I’m afraid.

This starter is tailored for large apps (and as you said, maybe overkill for small apps). When I mean that you use the same code base, I mean exactly that: the same source code is used to build both a web app and an hybrid app. If done well, the time gained can be huge, and taking in example my current app there even be some functional differences (hybrid app has offline support through native part, qrcode scan, photo/video recording… while web app have admin and premium accounts management extra pages), still running through the same source code.

As for the components, I always found the ionic scss to be extremely easy to adapt and make suited also for web apps. There’s a few glitches sure, but there was (almost) always easy fixes for my cases.

Back from vacation, I pulled a quick update to the docs regarding the limitations: https://github.com/ngx-rocket/generator-ngx-rocket/pull/118/commits/5470b69a66f1c997a58146c6c5267dae6076c733

@Sujan12: Does the changes make it feel more accurate to you?

Suggestions welcome :slight_smile:

The changes sound good and honest.

Just a quick update: PWA support is now baked in with @angular/service-worker, here is the out-of-the-box result with https://github.com/ngx-rocket/cli and https://github.com/ngx-rocket/addon-firebase :

:blush:

2 Likes

Seems interesting! I will try it for my app since ionic cli is giving me headaches trying to implement a meteor backend. However, I believe this one can be adapted to meteor. I am following this tutorial: https://angular-meteor.com/tutorials/whatsapp2/ionic/setup

Im happy to discover this thread. I was basically doing the same work on our enterprise project. Ionic is going too far from Angular and create so too many disappointment. The last in date and the reason I started to move our project in a regular Angular-cli is the AOT failure on Ionic. Asking a mobile device to compile typescript is a bit hard to understand.

In my opinion Ionic-cli should only wrap cordova and angular-cli.

Anyway gonna check your project!

Thanks you

Huh? Could you expand on that?

There is two way to compile Angular JIT and AOT basically:

  • In JIT mode the CLI (computer) do the first part of the building process (concatenation, scss compilation etc…) but send Typescript to the browser and it’s the browser who compile the typescript using ngc in Ionic case the browser is on smartphone.

  • In AOT the difference is that the CLI (computer) also do the typescript compilation using ngc and the project totally compiled is send to the browser.

In a web app context the cli and the browser are on our computer with powerfull CPU and the difference of using JIT vs AOT is not a major difference but in mobile app context it’s just impossible to ask a mobile device to compile a big angular app.

Our Ionic App has 32 pages, in JIT the cli building part is around 3sec and the ngc compilation on the browser is about 20sec. With AOT is 3sec + 2sec for ngc.

So 23sec in JIT before the page is updated on the mobile phone and 5sec with AOT.