Toilet EvolutionのフロントエンドをPolymer3対応する(3)
Saturday, April 27, 2019 07:16:00 PM
この記事はToilet EvolutionのフロントエンドをPolymer3対応する(2)の続編です。
今回もmozlier適用だけでは動かないので、ローカルで動作するように修正というコミットにおける試行錯誤を書いていきます。
前回は多くのアプリケーションや、カスタムエレメントで実施しなければならない共通的な修正箇所について解説しましたが、ここからはアプリケーションで使っている機能やエレメントについて、修正が必要だった箇所について解説していきます。
ES Module対応になっていないエレメントを使う
前回の記事で「bower_components を使わないようにする
」について解説しました。
PolymerチームやVaadinチームなどが作っているコンポーネントについては、ほとんど ES Module
に対応しているのですが、場合によっては対応してないモジュールを使っていることがあるかもしれません。
Toilet Evolutionでは以下のエレメントが ES Module
に対応していませんでした。iron-signals
は toast-er
の依存に関連しています。
そこで、これらのエレメントは modulizer で変換されたものを、そのまま利用することにしました。
また変換されたエレメントについては、前回の記事同様に共通的な修正箇所が必要になります。
つまり自分で作ったエレメントと同様に、そのエレメントが依存している(bower.jsonに含まれている)エレメントやライブラリについても、 npm install
で取得するように変更する必要があります。
またPolymer1用のライブラリだったりする場合は、Polymer1から2へのアップグレードガイドに書いてある slot
の対応なども必要だったので、そのライブラリが最新版だとPolymerのどのバージョンに対応したものなのかを確認しておくことが重要です。
そして、これらの作業が結構やっかいです(自分で作ったものでないので、ソースを理解する必要があります)。
以前のPolymerのビヘイビアは個別にインストールする必要がある
HTMLインポートで利用していた、Polymerチームが作っていたようなカスタムエレメントのビヘイビアは、個別に import
するか、場合によっては npm install
で導入する必要があります。
自分で作ったエレメントでは、ビヘイビアを使っていなかったので、この段階で初めて知りました(これは意外にもドキュメントに書いていません)。
例えば <gold-password-input>
では、PaperInputAddonBehavior
という paper-input
に含まれていたビヘイビアを使っています。
これは以下のように、import
を追加してあげる必要があります。
import {PaperInputAddonBehavior} from '@polymer/paper-input/paper-input-addon-behavior.js';
ES Module
対応しているエレメントであれば、webcomponents.orgのビヘイビアを参照すると解説が書いてあります。
上記の PaperInputAddonBehavior
であれば、こちらです。
Polymer.dom を変更する
これも自分のエレメントでは使っていなかったので気付かなかったのですが、使っているエレメントがあったので修正の必要がありました。
まず dom
をインポートします。
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js'
で、Polymer.dom
を使っている箇所を dom
に変更します。例えば以下のような感じです。
return dom(this).parentNode;
bowerでカスタムエレメント以外のライブラリに依存している
<gold-password-input>
はzxcvbnというパスワードストレングスエミュレータを使っています。
Node.jsなどにも対応しているのですが、今回はbowerでインストールしたフォルダをそのままコピーして、リポジトリに追加しました。
このようにカスタムエレメント以外のライブラリを使っている場合は、npmでインストールしてビルドする方法以外の検討も必要となります。
特に<gold-password-input>
では、以下のように script
タグを動的に追加してライブラリをインポートしていたため、npmを利用するのに適していなかったという理由があります。
ready: function() {
isZxcvbnLoaded = typeof zxcvbn !== "undefined";
if (!isZxcvbnLoaded) {
isZxcvbnLoaded = true;
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.onerror = function(err) {
isZxcvbnLoaded = false;
throw new URIError("The script " + err.target.src + " is not accessible.");
};
this.parentNode.insertBefore(oScript, this);
oScript.src = this.resolveUrl("../zxcvbn/dist/zxcvbn.js");
}
},
このぐらいまで対応が進むと、ページをロードしたときに、ブラウザのコンソールにエラーが出ることが少なくなります。
ただし多くのページで表示が崩れていたり、うまく表示できないエレメントがあります。
これは今回の ES Modules
に対応してなかったエレメントに関連するところなのですが、
これらの対応方法については次回解説していきます。
Toilet EvolutionのフロントエンドをPolymer3対応する(2)
Friday, April 26, 2019 04:47:00 PM
この記事は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の変更
shell
や fragments
で指定したファイルの拡張子を 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
を変更していますが、これを例に説明します。
- まずwebcomponents.orgのサイトでWebComponentsを検索します。
- この例では
polymer
を入力して検索すると、該当のものが見つかるので、詳細ページを開きます。 - もし
ES Modiles
に対応していれば、左側にView on NPM
が表示されます。 INSTALLED VIA NPM
のリンクをクリックするとnpm install --save Polymer/polymer
のように表示されるので、CLIからインストールします。- 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)
Thursday, April 25, 2019 03:42:00 PM
私が開発運用しているToilet Evolutionは、フロントエンドをPolymer(v1)で構築していました。 これは古いWebComponentsの仕組みを使っているので、常々アップデートしないとなーと思いながらも、長いこと重い腰があがりませんでした。
しかし以下のツイートを見て「よしやるぞ」という気持ちにスイッチが入り、移行を実施しました。
PSA: The latest Chrome Canary has removed support for web components v0, per the deprecation plan announced last year.
— Polymer Project (@polymer) 4 March 2019
If you have a site built with Polymer 1.x (or web components v0), check it against Canary now to make sure you’re properly serving the polyfills. https://t.co/IElNjGGZbI
実際Toilet Evolutionのサイトはもう最新に置き換わっております。 その様子はToilet EvolutionのGitHubリポジトリのコミットログを追うことでもわかったりしますが、かなり頑張ったので、その過程を連載でブログにまとめようと思いました。
この記事はその1回目です。
Polymer1プロジェクトをPolymer3へ移行するには
マイグレーションガイドは1から2、2から3に向けてあります。 1から3のガイドがあるわけではないので、両方を事前に読んでおくと良いです。
- Polymer1から2へのアップグレードガイド
<dom-module>
でname
を使っていたらid
に変更。styles
タグはtemplate
タグの内側へ<content>
タグは<slot>
タグへ- CSSの
::content
セレクタは::slotted()
セレクタへ - CSSの
/deep/
や::shadow
は使えなくなる - などなど…
- Polymer2から3へのアップグレードガイド
- modulizer使うと簡単にできるよ!
Polymer2は1の記法が使えるハイブリッドモードがあるのと、そもそも1から2で変更が必要な記述を使っていないので、実際はmodulizer一発でいけるんでは?と考えました。 なので、1から2の手順は気にせず、進むことにしました。
何はともあれアップデート
npmのライブラリもだいぶ古くなっていたので、まずは最新に更新しました。
Gulpを3から4にあげたので gulpfile.js
もモリモリと変えていきます。
続いて、bowerに入っているパッケージも新しくしていきます。これは modulizerのガイドに書いてあるので、そのまま実施します。
続いてmodulizerを実行しますが、commitログではそこまでの手順で迷走しています。あまり気にしないでくださいw
modulizerで変換する
modulizer --out .
を実行します。すると html で記述していたカスタムエレメントが js ファイルに変更されます。
ここまでのコミット
変換するとだいたい良い感じになっています。 でも変換だけでは動きません。ここで以下のような箇所が変換されないことがわかります。
- polymerの公式エレメントなど、変換されたbower_componentsを参照していて、npmに切り替わらない
- 変換後に手動で書き換えることに書いてある手順の実施
これらの手順は次回へ続きます。
esm LTでブラウザの最新動向について話しました
Sunday, April 07, 2019 01:47:00 PM
esm LTとは永和システムマネジメントの社内LT大会のようなもので、福井にゆかりのあるやきとりの名門 秋吉のやきとりとビールを片手にワイワイ楽しむイベントです。
勤務先の ESM LT #4 の設営がされている🐓🔥🍻 pic.twitter.com/HhvohEDh2j
— Koichi ITO (@koic) 5 April 2019
自分で写真撮るの忘れたので、同僚のツイートを引用。
私が話したのは「ブラウザの最新動向について」ということで、PHPerKaigiでも話した import maps と、Chrome73から入ったDevToolsの Add Logpoints
について話しました。
ChromeのDevToolsに入った新しい機能とか、そもそもWeb Updatesみんな読んでないよね、ってことで、新しい機能便利なんでみんな読もう!ってことです。
Logpointsに関してはWhat’s New In DevTools (Chrome 73)の記事を読んでください。
最初に紹介されます。
これからみんなソースコードにデバッグ用途の console.log()
を書くの禁止な!
PHPer Kaigi 2019に参加しました
Sunday, April 07, 2019 01:00:00 PM
初めてのPHPerKaigi参加です。 これまで予定が重なっていて参加できなかったのですが、今年は年度末開催ということで、他の予定もなく参加することができました。
どうせなら何か話さないと、ということで
- Day2 の IRT: テスト〜CI/CD相談会 で、 @kaz_29 のテーブルトークの賑やかしに
- Day3 のアンカンファレンスで ブラウザの次に来る(かも?しれない)仕様を知ってフロントエンドチョットデキル人になろうというテーマで話す
- Day3 の IRT: フロントエンド相談会 で、 @FruitRiin のテーブルトークの賑やかしに
- Day3 の 出張版PHP勉強会@東京で、メインセッションを担当
他はセッションを聞いていました。
CI/CDとは…
CI/CD相談会で受けた印象は、CI == 自動テストやってます、CD == ツール使ってデプロイしてます(完全手動ではない)という雰囲気の人が多く、ほんとうのCI/CDにはまだまだ遠いなぁという感じ。それでも私がテストやろうね、といってほとんどの人が書いてない時代からは大きな変化で、いつかほんとうの意味に近づいてくれることを期待しています。
import maps と HTML Template Instantiation について
アンカンファレンスではWeb Componentsの周辺仕様の動きについて、話しました。
このうちCSS Shadow PartsはCSSWGのドラフトになっていることもあり、概要をさらっと説明。 Custom Element RegisterとHTML Modulesは、Web Components色が強いので、これも概要をさらっと。 で、import mapsとHTML 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楽しかったですね。
IRTフロントエンド相談会、なんとかいい感じに終わったかと思います。 @sizuhiko さん回すの手伝ってくれてありがとでした!#phperkaigi
— 果物リン (@FruitRiin) 31 March 2019
出張版PHP勉強会@東京で話しました。
「PHPを学ぶということ」というタイトルで初心者セッションをやりました。
最近PHP勉強会で初心者の人多いなーと感じることが多いのと、開発チームでもプログラミングこれから!みたいな人にどうしたら良いのかなーと思うことがあって、まずは勉強の入り口にどうしたら良いかというキッカケを作ることができれば良いと思いました。
PHPコミュニティのSlackへの参加者が、このセッションをきっかけに結構増えたので、良かった!
さいごに
PHPerKaigi とても楽しかった。 交流がメインのカンファレンスらしく、多くの人と、様々な話題について議論できました。 さぁ、次は福岡に行きますよ!
Recent Articles
- Rails 7の採用提案で注目を集め始めた Import maps の過去、現在、そして未来について... 2022/05/06
- Middleman を 3系から 4系にアップグレードした 2022/05/06
- uvu での Test Double 2022/05/05
- GitHub Enterprise の Actions で依存関係を S3 にキャッシュする 2022/05/05
- TypeORM でプライマリーキーや外部キーの名前を変更する 2022/05/04
- TypeORM を 0.3 系にアップグレードする 2022/05/04
- DependabotをGHEのActionsとPackagesで利用する 2022/05/03
- @swc-node/jest を使ってテストを高速化する 2022/05/03
- pong-swoosh のアップデートまとめ 2022/05/02
- オンラインイベントの盛り上がりを効果音で共有するサービス pong-swoosh を作成した 2021/07/11