LoginSignup
3
2

More than 3 years have passed since last update.

WebComponentsを各種ライブラリを使って試したメモ

Last updated at Posted at 2019-05-10

web componentでHello World

WEB+DBで記事の特集をしていたので試してみた。
ビルド環境の作成にはdockerを使用。
ついでに、angularやelmなども試した。

この時点のソース

サイズ比較

Hello worldを表示するだけのWeb Componentでの比較なので、
ほぼライブラリ部分の容量。

vagrant@ubuntu-bionic[master]: $ ls ../server/dist/ -alh
total 448K
drwxrwxrwx 1 vagrant vagrant    0 May 10 08:33 .
drwxrwxrwx 1 vagrant vagrant    0 May 10 08:33 ..
-rwxrwxrwx 1 vagrant vagrant 3.2K May 10 20:55 tsApp.js
-rwxrwxrwx 1 vagrant vagrant  26K May 10 20:56 elmApp.js
-rwxrwxrwx 1 vagrant vagrant  79K May 10 20:57 vueApp.js
-rwxrwxrwx 1 vagrant vagrant 120K May 10 20:47 reactApp.js
-rwxrwxrwx 1 vagrant vagrant 215K May 10 08:07 angularApp.js

記述比較

Vue

vue-app/src/App.vue
<template>
  <div>
    <p>Vue-app</p>
  </div>
</template>
vue-app/src/index.js
import Vue from 'vue';
import App from './App';
import vueCustomElement from 'vue-custom-element';

Vue.use(vueCustomElement);

Vue.customElement('vue-app', App);

React

react-app/src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <div>React-app</div>;
  }
}

// Custom ElementとするためにHTMLElementを継承
class CustomElementsApp extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('div');
    this.attachShadow({ mode: 'open' }).appendChild(mountPoint);
    ReactDOM.render(<App />, mountPoint);
  }
}

customElements.define('react-app', CustomElementsApp);

Elm

elm-app/src/App.elm
module App exposing (main)

import Html exposing (Html, text)


main : Html msg
main =
    text "Elm App"
elm-app/src/index.js
const { Elm } = require("./App.elm");

class ElmApp extends HTMLElement {
  connectedCallback() {
    Elm.App.init({ node: this });
  }
}

customElements.define("elm-app", ElmApp);

Angular

angular-app/src/app.component.ts
import { Component, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { HelloComponent } from './hello/hello.component';

@Component({
  selector: 'angular-app',
  template: ``,
})
export class AppComponent {
  constructor(
    private injector: Injector,
  ) {
    const AppHelloElement = createCustomElement(
      HelloComponent,
      { injector: this.injector }
    );
    customElements.define('angular-app', AppHelloElement);
  }
}
angular-app/src/app/hello/hello.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-hello',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.css']
})
export class HelloComponent {
  title = 'angular-app';
}
angular-app/src/app/hello/hello.component.html
<!--The content below is only a placeholder and can be replaced.-->
<div>
  {{ title }}!
</div>
angular-app/src/app/app.module.ts
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';

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

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, HelloComponent],
  bootstrap: [AppComponent],
  entryComponents: [HelloComponent]
})
export class AppModule { }
angular-app/src/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';

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

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

Typescript

ts-app/src/index.ts
class TsApp extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    const wrapper = document.createElement('span');
    wrapper.setAttribute('class', 'wrapper');
    const info = document.createElement('span');
    info.setAttribute('class', 'info');
    info.textContent = 'ts-app';
    shadow.appendChild(wrapper);
    wrapper.appendChild(info);
  }
}
customElements.define('ts-app', TsApp);

ひっかかったところ

angularは最新版のtsやcore-jsではエラーとなるらしい。。
あとコンテナにchromeが入っていなかったのでインストール。これはkarma用。

angular-app/docker/angular/Dockerfile
FROM node:11.15.0

# コンテナ上の作業ディレクトリ作成
WORKDIR /app

RUN yarn add --dev \
  @angular/compiler-cli \
  @angular-devkit/build-angular \
  @angular/cli \
  @angular/language-service \
  @types/jasmine \
  @types/jasminewd2 \
  @types/node \
  codelyzer \
  jasmine-core \
  jasmine-spec-reporter \
  karma \
  karma-chrome-launcher \
  karma-coverage-istanbul-reporter \
  karma-jasmine \
  karma-jasmine-html-reporter \
  protractor \
  ts-node \
  tslint

RUN yarn add \
  @angular/animations \
  @angular/common \
  @angular/compiler \
  @angular/core \
  @angular/elements \
  @angular/forms \
  @angular/http \
  @angular/platform-browser \
  @angular/platform-browser-dynamic \
  @angular/router \
  rxjs \
  zone.js \
  document-register-element 

# ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.3.0 but 3.4.5 was found instead.
RUN yarn add --dev typescript@3.2.x
# core-js 3.0系だとエラー
RUN yarn add core-js@2.6.x
# test用
RUN \
  apt-get update && \
  apt-get install -y wget curl unzip apt-utils && \
  mkdir -p /home/root/src && cd $_ && \
  wget -q -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip && \
  unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/ && \
  apt-get install -y libappindicator1 fonts-liberation libasound2 libnspr4 libnss3 libxss1 lsb-release xdg-utils && \
  touch /etc/default/google-chrome && \
  wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb 
RUN apt-get install -y libappindicator3-1 \
  libatk-bridge2.0-0 \
  libatspi2.0-0 \
  libgtk-3-0 
RUN cd /home/root/src && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb  && dpkg -i google-chrome-stable_current_amd64.deb && \
  apt-get install -y fonts-migmix

参考

WEB+DB PRESS vol.110
単一コンポーネントのエラーの」解決
Docker Composeを使ってサクッとNginxコンテナを起動する
Elm と他のフレームワークを組み合わせる
npm
angular component
docker-composeでangular-cliの環境を作ってみる
Dockerでheadless-chromeを使ったスクレイピング環境を整える
UbuntuにChromeをインストールする
karma headless chrome
lit-htmlとバニラWeb Componentsでコンポーネントを実装する
“Web Componentsだけ” で新サービスを実装して見えたこと

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2