See how Stencil fits into the entire Ionic Ecosystem ->
Stencil is part of the Ionic Ecosystem ->

Angular

Stencilで構築されたWebコンポーネントコレクションをAngular CLIのプロジェクトで使用するには、次の2段階のプロセスが必要です。

  1. コンポーネントを使用するモジュールにCUSTOM_ELEMENTS_SCHEMAを含める。
  2. main.ts(または他の適切な場所)から、defineCustomElements()を呼び出す。

Custom Elementsのスキーマを含める

モジュールにCUSTOM_ELEMENTS_SCHEMAを含めると、コンパイラがエラーを出すことなくHTMLのマークアップでWebコンポーネントを使用できます。このコードは、AppModuleとCustom Elementsを使用する他の全てのモジュールに追加する必要があります。 次はAppModuleに追加する例です。

import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, FormsModule],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

CUSTOM_ELEMENTS_SCHEMAは、Custom Elementsを使用する全てのモジュールに含める必要があります。

defineCustomElementsを呼び出す

Stencilで作成されたコンポーネントコレクションには、コレクション内のコンポーネントを読み込むためのメイン関数が含まれています。その関数はdefineCustomElements()と呼ばれ、アプリケーションの起動中に一度呼び出す必要があります。これを行うのに便利な場所の1つとして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';

// Note: 出力ターゲット設定の"esmLoaderPath"で設定されたローダーをインポート
import { defineCustomElements } from 'test-components/loader';

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

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

EdgeとIE11のポリフィル

Custom Elementsを古いブラウザで動作させるには、defineCustomElements()applyPolyfills()で囲む必要があります。

import { applyPolyfills, defineCustomElements } from 'test-components/loader';
...
applyPolyfills().then(() => {
  defineCustomElements()
})

ViewChildやViewChildrenを使用したコンポーネントへのアクセス

次の例のようにViewChildViewChildrenを使用してコンポーネントを参照できます。

import {Component, ElementRef, ViewChild} from '@angular/core';

import 'test-components';

@Component({
    selector: 'app-home',
    template: `<test-components #test></test-components>`,
    styleUrls: ['./home.component.scss'],
})
export class HomeComponent {

    @ViewChild('test') myTestComponent: ElementRef<HTMLTestComponentElement>;

    async onAction() {
        await this.myTestComponent.nativeElement.testComponentMethod();
    }
}

Bindings

Angular has a pretty good story for integration with web components but there are a few issues with the developer experience. With bindings, the web components get wrapped in an Angular component and then immediately become available as Angular Components. Some of the advantages of doing this are that you get types for your components and you also get the ability to use ngmodel on inputs. Your developers then consuming your web components from Angular applications import an actual Angular Library and to them it feels as though they are interacting with Angular components.

Install

npm install @stencil/angular-output-target --save-dev

Stencil Config setup

To make use of the AngularOutputPlugin first import it into your stencil.config.ts file. Then add it as an OutputTarget.

import { Config } from '@stencil/core';
import { angularOutputTarget, ValueAccessorConfig } from '@stencil/angular-output-target';

export const config: Config = {
  namespace: 'demo',
  outputTargets: [
    angularOutputTarget({
      componentCorePackage: 'component-library',
      directivesProxyFile: '../component-library-angular/src/directives/proxies.ts',
      valueAccessorConfigs: angularValueAccessorBindings,
    }),
    {
      type: 'dist',
    },
  ],
};

componentCorePackage

This is the NPM package name of your core stencil package. In the case of Ionic we chose ‘@ionic/core’. This is the package that gets published that contains just your web components. This package is then used by the Angular package as a dependency

proxiesFile

This is the output file that gets generated by the outputTarget. This file should be referencing a different package location. In the example case we are choosing a sibling directory’s src directory. We will then create an Angular package that exports all components defined in this file.

valueAccessorConfigs

In order for ngmodel to work on input components we need to define certain pieces of information about the input components. Unfortunately the Stencil compiler cannot infer the intent of components because this is a very conceptual idea.

Setup of Angular Component Library

There is an example component library package available on Github so that you can get started. This repo will likely live as a sibling to your Stencil component library. https://github.com/ionic-team/stencil-ds-angular-template

Usage

import { ComponentLibraryModule } from 'component-library-angular';

@NgModule({
  ...
  imports: [
    ComponentLibraryModule
  ],
  ...
})
export class AppModule { }
BackNext
Contributors