highcharts
TypeScript
AngularJS
ionic
WebComponents

未定義なHTMLタグをTypeScriptで使いたい!でもビルド警告は消したい!

この記事は BRIGHT VIE Advent Calendar 2017 9日目の記事になります。

なぜ未定義のHTMLタグを使う必要があったのか

弊社のグラフインターフェイスは Highchartsを使うことが多く、
ネットにあったサンプルをIonicのビューへ貼り付け、そこからロジックをカスタマイズをします。

仕様に合わせていろいろ組み込んでますが、こんな感じでしっかり動きます。

スクリーンショット 2017-12-08 11.41.03.png

で、改めてHTMLコードをみると、こんなコードになっています。

<chart></chart>

ってHTMLタグが使われていました。
chartタグを使う必要は全くなかったのですが、
「ここにグラフが描画されるってのは、コードの可視性としてはちょっとわかりやすいなぁ」と思い、
「未定義なHTMLタグって使っていいんだろうか?」と考えました。

未定義なHTMLタグ、使って良いのか?

どうやら「HTMLUnknownElement:未定義なHTMLエレメント」として、仕様上は許可されているようです。

HTMLUnknownElement

褒められた使い方ではないにしても、
絶対に使っちゃだめ!ということではないのかもしれませんw

TypeScriptではビルド警告がでる

ただ、VSCodeなどでは、警告がでます。

スクリーンショット 2017-12-08 11.30.34.png

カーソルをあてると、以下のような警告がでていました。

[Angular]
'chart' is not a known element:
1. If 'chart' is an Angular component, then verify that it is part of this module.
2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

こんなタグしらないとおこられています。

HTMLUnknownElementを使用しても警告がでないようにする

「未定義なタグも許可してね」と定義します。
NO_ERRORS_SCHEMAのimportと、@NgModule.schemasへの追加でOKです。

home.module.ts
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; //← NO_ERRORS_SCHEMA 追加
import { IonicPageModule } from 'ionic-angular';
import { CarenoteBrowseOneGraphPage } from './carenote-browse-one-graph';
import { ComponentsModule } from '../../../../components/components.module';
import { ChartModule } from 'angular2-highcharts';
declare var require: any;
const Highcharts = require('highcharts');

@NgModule({
  declarations: [
    HomePage,
  ],
  schemas: [    //← schemasへNO_ERRORS_SCHEMAを追加
    NO_ERRORS_SCHEMA
  ],
  imports: [
    ChartModule.forRoot(Highcharts),
    IonicPageModule.forChild(HomePage),
    ComponentsModule,
  ],
})
export class HomePageModule {}

定義外のHTMLタグを使う事自体が、バッドノウハウであるとは認識していますが、
HTMLのわかりやすさを重視する場合にはこういった回避策もあるのかもしれません!

(追加:2017/12/08)
コメントで指摘いただきましたように、
Web Componentsの仕様で「ハイフンが必須」ということもあるようですので、
独自にタグをつけちゃう場合には

<my-chart></my-chart>

と定義し、

home.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; //← NO_ERRORS_SCHEMA 追加

@NgModule({
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA
  ],
})
export class CarenoteBrowseOneGraphPageModule {}

とするのが、ベストプラクティスのようです!
Web Componentsの構成要素まとめ(基本編)

参考URL

NgModule#schemas
NgModule#schemas - NO_ERRORS_SCHEMA