Technote

by sizuhiko

Toilet EvolutionのフロントエンドをPolymer3対応する(2)

この記事はToilet EvolutionのフロントエンドをPolymer3対応する(1)の続編です。

今回からはmozlier適用だけでは動かないので、ローカルで動作するように修正というコミットにおける試行錯誤を書いていきます。

うまく動作させるために試行錯誤して変更したファイル、実に110。1回では書ききれない予感が…

不要になったファイルを削除

bower.json.bowerrc ファイルは、Polymer3でnpmに移行したので、削除します。

linterを追加

lintは polymer-cli にも付いているのですが、エディタで編集中にも状況は知りたいので、eslintを導入します。 Polymer1のころはHTMLファイルだったので、特に不要でしたね。

ビルドを変更

これまでbuildは独自にgulpで実装していたのですが、Polymer3対応をするに伴いpolymer-buildを使うようにしました。 これは polymer CLI でも使っているビルドライブラリです。ビルドについては、この連載で触れていきます。

polymer.jsonの変更

shellfragments で指定したファイルの拡張子を html から js に変更します。 これは自動的に変換されないので注意しましょう。 extraDependencies や、そのほかの定義も変わっていますが、このあたりはpolymer.json specificationを参考にPolymer3形式に1から記述するぐらいの気持ちでいましょう。

変換された自作のカスタムエレメントを修正する

まずmodulizerで変換すると、Polymer本体のimportが

import '../bower_components/polymer/polymer-legacy.js';

のようになっているので、これを

import '@polymer/polymer/polymer-legacy.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
import {html} from '@polymer/polymer/lib/utils/html-tag.js';

のように変更しました。

なお、公式ドキュメントによると

import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';

にしていますが、これは PolymerElement 使っている場合なので、ハイブリッドモードの書き方の場合は、私のようにlegacyを使ってください。

続いてテンプレートが以下のように Polymer.html を参照するようになっています。

Polymer({
  _template: Polymer.html`

この記述は利用できないので、以下のように import した html を利用するように変更します。

Polymer({
  _template: html`

bower_components を使わないようにする

変換されたjsファイルは、bower_components上に変換されたモジュールを参照しにいきます。 そこで各々のパッケージがnpmに公開されているか調べて、npmに移行していきます。

すでに上記で bower_components/polymer を変更していますが、これを例に説明します。

  1. まずwebcomponents.orgのサイトでWebComponentsを検索します。
  2. この例では polymer を入力して検索すると、該当のものが見つかるので、詳細ページを開きます。
  3. もし ES Modiles に対応していれば、左側に View on NPM が表示されます。
  4. INSTALLED VIA NPM のリンクをクリックすると npm install --save Polymer/polymer のように表示されるので、CLIからインストールします。
  5. bower_componentsから、参照しなくなったjsファイルを削除します。

WebComponents V1対応に追従する

自分が記述したCustomElementsには利用していなかった <content> も、依存関係のタグでは利用している場合があります。 例えば@polymer/app-layoutは、レイアウトないのコンポーネントを識別するときに利用しているので、slot対応を行います。たとえば以下のドロワー記述は

      <app-drawer>

次のように slot 識別を追加します。

      <app-drawer  slot="drawer">

このあたりの修正ポイントは、タグが表示されなくなることで気がつきますが、アップデートしたら最新のドキュメントを一読することをオススメします。 他にも修正箇所があるかもしれませんので。

importHref を修正する

iron-pages でページを切り替えるとき、Polymer1では動的に HTML import を実行していました。

  _pageChanged: function(page) {
    this.importHref('/elements/te-' + page + '.html', null, null, true);

ES Moduleを使うPolymer3では以下のように書き換えます。

    switch (page) {
      case 'admin':
        import('./te-admin.js');
        break;
      case 'devices':
        import('./te-devices.js');
        break;
      case 'login':
        import('./te-login.js');
        break;
      case 'about':
        import('./te-about.js');
        break;
    }

import の引数には変数が利用できないので注意してください。

Polyfillを変更する。

HTMLファイルではpolyfillLをインポートしています。 Polymer1では /bower_components/webcomponentsjs/webcomponents-lite.min.js を使いましたが、Polymer3では以下のpolyfillに変更します。 これもnpmを使ってインストールするように変更します。

<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>

このように修正を重ねていくことで、徐々に動作するエレメントが増えてきます。 ここまでは多くのアプリケーションや、カスタムエレメントで実施しなければならない共通的な修正箇所です。 Toilet Evolutionでは、まだまだ修正箇所がありましたので、続きは次回で。

Toilet EvolutionのフロントエンドをPolymer3対応する(1)

私が開発運用しているToilet Evolutionは、フロントエンドをPolymer(v1)で構築していました。 これは古いWebComponentsの仕組みを使っているので、常々アップデートしないとなーと思いながらも、長いこと重い腰があがりませんでした。

しかし以下のツイートを見て「よしやるぞ」という気持ちにスイッチが入り、移行を実施しました。

実際Toilet Evolutionのサイトはもう最新に置き換わっております。 その様子はToilet EvolutionのGitHubリポジトリのコミットログを追うことでもわかったりしますが、かなり頑張ったので、その過程を連載でブログにまとめようと思いました。

この記事はその1回目です。

Polymer1プロジェクトをPolymer3へ移行するには

マイグレーションガイドは1から2、2から3に向けてあります。 1から3のガイドがあるわけではないので、両方を事前に読んでおくと良いです。

Polymer2は1の記法が使えるハイブリッドモードがあるのと、そもそも1から2で変更が必要な記述を使っていないので、実際はmodulizer一発でいけるんでは?と考えました。 なので、1から2の手順は気にせず、進むことにしました。

何はともあれアップデート

npmのライブラリもだいぶ古くなっていたので、まずは最新に更新しました。 Gulpを3から4にあげたので gulpfile.js もモリモリと変えていきます。

続いて、bowerに入っているパッケージも新しくしていきます。これは modulizerのガイドに書いてあるので、そのまま実施します。

続いてmodulizerを実行しますが、commitログではそこまでの手順で迷走しています。あまり気にしないでくださいw

modulizerで変換する

modulizer --out . を実行します。すると html で記述していたカスタムエレメントが js ファイルに変更されます。 ここまでのコミット

変換するとだいたい良い感じになっています。 でも変換だけでは動きません。ここで以下のような箇所が変換されないことがわかります。

これらの手順は次回へ続きます。

esm LTでブラウザの最新動向について話しました

esm LTとは永和システムマネジメントの社内LT大会のようなもので、福井にゆかりのあるやきとりの名門 秋吉のやきとりとビールを片手にワイワイ楽しむイベントです。

自分で写真撮るの忘れたので、同僚のツイートを引用。

私が話したのは「ブラウザの最新動向について」ということで、PHPerKaigiでも話した import maps と、Chrome73から入ったDevToolsの Add Logpoints について話しました。

ChromeのDevToolsに入った新しい機能とか、そもそもWeb Updatesみんな読んでないよね、ってことで、新しい機能便利なんでみんな読もう!ってことです。

Logpointsに関してはWhat’s New In DevTools (Chrome 73)の記事を読んでください。 最初に紹介されます。 これからみんなソースコードにデバッグ用途の console.log() を書くの禁止な!

PHPer Kaigi 2019に参加しました

初めてのPHPerKaigi参加です。 これまで予定が重なっていて参加できなかったのですが、今年は年度末開催ということで、他の予定もなく参加することができました。

どうせなら何か話さないと、ということで

他はセッションを聞いていました。

CI/CDとは…

CI/CD相談会で受けた印象は、CI == 自動テストやってます、CD == ツール使ってデプロイしてます(完全手動ではない)という雰囲気の人が多く、ほんとうのCI/CDにはまだまだ遠いなぁという感じ。それでも私がテストやろうね、といってほとんどの人が書いてない時代からは大きな変化で、いつかほんとうの意味に近づいてくれることを期待しています。

import maps と HTML Template Instantiation について

アンカンファレンスではWeb Componentsの周辺仕様の動きについて、話しました。

このうちCSS Shadow PartsはCSSWGのドラフトになっていることもあり、概要をさらっと説明。 Custom Element RegisterHTML Modulesは、Web Components色が強いので、これも概要をさらっと。 で、import mapsHTML Template Instantiationについて、少し深く話しました。

import maps

これは過去のブログ記事でも登場した Package name maps の最新の名前です。過去のリンクからは自動的にリダイレクトされます。 bower によるJavaScript依存ライブラリのインストールが、npm中心のエコシステムに変わり、ブラウザからそのモジュールを利用するには Webpack のようなもので依存解決をする必要がありました。 しかし今日では ESModule Import がブラウザでもサポートされているので、以下のようなコードでライブラリを利用したくなります。

import moment from "moment";
import { partition } from "lodash";

しかしブラウザは from から読み取るときURIとして識別するので、当然サーバーからJavaScriptファイルを取れないし、Node.jsと違って package.json から main のスクリプトファイルをロードすることもできません。 そこで import maps では以下のようなマッピング定義を使います。

{
  "imports": {
    "moment": "/node_modules/moment/src/moment.js",
    "lodash": "/node_modules/lodash-es/lodash.js"
  }
}

するとブラウザはマッピングファイルから以下のように記述されたものとして解釈します。

import moment from "/node_modules/moment/src/moment.js";
import { partition } from "/node_modules/lodash-es/lodash.js";

これはWeb Componentsに関係なく、普通にHTMLからjQueryを使おうとしていた人にとってもわかりやすくなるし、Webpackからも解放されるので、はやくブラウザ実装になってほしいなぁと思っています。

HTML Template Instantiation

「テンプレートエンジンをブラウザ自体に」というのがこの仕様なわけですが、様々なフレームワークや handlebars のようなライブラリまで、テンプレートエンジンは数多くあります。ブラウザでやることは車輪の再開発なのか?という点については、RawレベルのAPIが利用可能になることでDOMの書き換えをブラウザがやってくれることはスピードアップにつながるし、ぜひとも進んでほしい仕様の一つです。 PolymerチームのJustinなど、各ブラウザベンダーの人も議論に参加しているので、期待できます。

フロントエンド相談会

Reactを使う人、Vueを使う人、Web Componetsを推進したい人(私)など、様々なお悩み、SSRの話しなども出ました。 技術ワードに踊らされるのではなく、それぞれの課題に対して議論できたのがとても良かったです。 IRT楽しかったですね。

出張版PHP勉強会@東京で話しました。

「PHPを学ぶということ」というタイトルで初心者セッションをやりました。

最近PHP勉強会で初心者の人多いなーと感じることが多いのと、開発チームでもプログラミングこれから!みたいな人にどうしたら良いのかなーと思うことがあって、まずは勉強の入り口にどうしたら良いかというキッカケを作ることができれば良いと思いました。

PHPコミュニティのSlackへの参加者が、このセッションをきっかけに結構増えたので、良かった!

さいごに

PHPerKaigi とても楽しかった。 交流がメインのカンファレンスらしく、多くの人と、様々な話題について議論できました。 さぁ、次は福岡に行きますよ!

Polymer.co-edo meetup #23を開催しました

2019年2回目となる Polymer.co-edo ミートアップ を開催しました。

今回、私はいよいよEdoエレメントの作成に入りました。 名前は edo-blogcard です(まだリポジトリをPUSHしてないので、upしたら別の記事にします)。 これは、はてな等でブログにリンク先のサムネ、タイトル、概要の部品が入っているのを見たことがあると思うのですが、あれです。 これを LitLoader を使って作り始めました。

次回

2019年のGWに Polymer.co-edo day として開催予定を公開しています。 私が1日 co-edo で作業しているので、一緒にもくもくしたり、Web Components関連の質問を受け付けたり、 好きな時間に来て、帰ってもらっても大丈夫な1日になります。 皆様の参加をお待ちしております。

Doorkeeperのコミュニティページ