[Stencil] Importing Stencil components into Ionic-Angular


#1

I had a convo on a Github issue that took about half a day, because I didn’t fully understand how to import Stencil components into Ionic-Angular. I finally think I get it, and I’ve written up my understanding of the process.

Importing a Stencil component into Ionic-Angular

@reedrichards the part about copy.config.js was new to me, and it’s an improvement over what I (and I think you) was doing previously.


#2

@AaronSterling actually I was already doing like this (“create separate own copy.config.js file”), but I use the word “overwrite” to describe that, which wasn’t clear at all I notice now, thx :thumbsup:

I have now updated my own component README and also linked yours in EXAMPLE: Integration StencilJS Web Component in Ionic App

P.S.: btw. I do the same, “create a local copy.config”, for example to deploy the fontawesome (v4) fonts to the assets folder.


#3

Great job guys

Hope though that ionic team comes up with a nice CLI way of setting up Stencil integration with the popular frameworks like vue, react and angular

Or some nice documentation

Tom


#4

There’s an unofficial generator project here: https://github.com/AkashGutha/generator-stencil


#5

Hi,

Just out of curiosity. Why would I care about building components in StencilJS if I would want to stick with (ionic-)angular anyway? And not necessarily want to publish components for future use in other frameworks?

Obviously, I would care about IMPORTING Stencil components built by others (and hope, the Stencil site is going to host a great library of components,from Ionic team as well as the community).

Regards,

Tom


#6

Two main answers:

  1. You can totally ignore it and use Ionic as before.

  2. You can build your app in Stencil, and import Ionic components, for a much faster and smaller bundle.

One line about Stencil is that it offers 90% of what Angular offers, and is much faster. (Stencil has a router, which you can connect components with, but you don’t need to use it if you’re building standalone components.) Fair warning: I’ve temporarily stopped building in Stencil because I’m waiting for a bug with Cordova to be fixed. It’s pre-release for a reason.

The biggest difference in my eyes between Ionic 3 and 4 is that in 4 you don’t need to import everything. Maybe simplest to see this with ionicons. In ionicons 3, you need to import all the ionicons in order to use one. With version 4, you only need to import the ionicon you are using. Same thing is true with, say, ion-grid. You don’t need to import any other component.

Options (1) and (2) are opposite ends of a spectrum, maybe the simplest, but probably a lot of mixed strategies work too. To be determined.


#7

I’m waiting for stable Stencil.js, Capacitor, Ionic 4.
I can’t wait to try this new stack… and I hope this stack will beat React Native and NativeScript.

Btw, Angular 6 will be released on 28th this month.
Angular 7 is coming in September this year.
I wonder what they will bring to the table…


#8

I think Angular 6 will add “improvements” in the internationalization/translations. It seems that it gonna be possible to better load a language at boot time (I insist on the “it seems” or “maybe”, I really don’t have that much face in Angular and Internationalization I’ve to say, really disappointed by the solution they propose so far) and not to have to bundle different version of the app to support different languages, something like that. There is a great feed in https://github.com/ngx-translate/core/issues/783 about the future of ngx-translate and what will happens with angular. If you would be agree to support the guy behind ngx-translate, send him some kudos posts in this Github topic.

Regarding Stencil, I have published an update of my app which use my web component built with Stencil (https://github.com/peterpeterparker/web-photo-filter) in both Android and iOS stores. My tests on both types of devices were fine and so far I didn’t get an Sentry notifications that sh*ts in production happened, so I’m pretty happy :slight_smile:


#9

@reedrichards Here’s my issue. I don’t know what makes my component different from yours, but congrats! https://github.com/ionic-team/stencil/issues/571


#10

I did decide to don’t use shadowRoot for the moment, that probably explain why it’s working for me I guess


#11

I didn’t use it on purpose. Is there some flag where I can say “don’t use this” ?


#12

I think it’s in the decorator…let me check


#13

Do you have the following in your decorator:

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.scss',
  shadow: true // <------------------ Here use shadowRoot
})

#14

No. Maybe I should explicitly set it to false, just to be safe. I knew about that, but thought it wasn’t the issue, because I wasn’t using it. I should test.


#15

Maybe yes, but in my case I don’t explicitly set it to false. Also right now I use version 0.6.6.

Note: once I removed shadow:true I remember I had to modify something like this.el.querySelector or something because when you query without shadow dom it isn’t the same query anymore


#16

So I found, if no shadow root, you should modifiy

this.el.shadowRoot.querySelector...

to

this.el.querySelector...

#17

Interesting to see angular jumping the webcomponents bandwagon with Angular Elements

Makes me wonder why ionic team decided to make their own preprocessor instead of making ionic 3 easily available to other frameworks using elements


#18

For all those who end up here after searching for integrating Stencil:

The integration has been updated in the latest StencilJS docs. Refer to Framework Integration, angular for integrating it in Ionic(4) Angular app. LInk https://stenciljs.com/docs/angular.

Instead of importing the component directly, import a loader and call defineCustomElements(window) from main.ts

// File: main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import { defineCustomElements } from 'test-components/dist/loader';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
defineCustomElements(window);