このセッションでは、うつの部屋、両さんにご答えいただきます。グーテンベルク解体新書ということでお話いただきたいと思います。うつの部屋さんは、株式会社一級のソフトウェアエンジニアで、普段はジャバスクリプトによるキッチなUIの開発や、ワードプレスによる自社メディアサイト開発のサポートと同じあります。このセッションでは、ワードプレス5.0で導入される新エリタ、グーテンベルクに使われているリアクトをはじめ、バベルやベルザーク等の技術の紹介を通して、グーテンベルクをカスタマイズするプラグインの開発のポイントを詳しくお紹介いただきます。それでは、うつの部屋さん、よろしくお願いいたします。では、始めさせていただきます。最初に、軽く自己紹介をさせてください。株式会社一級という宿泊事業とかをやっている会社で、フロントエンドエンジニア、ウェブの画面を作る仕事をしています。主な仕事は、一級.comという宿泊予約サイトのUI開発とか、あとは一級コンシェルジというワードプレス制の自社メディアがありまして、そちらの改善の手伝い、技術サポートを使おうとしています。一級コンシェルジが最近、パフォーマンスを改善して、かなり速くなったので、ワードプレスサイトで、このぐらい速いサイトができるのを見ていただけるとすごい嬉しいです。今日のアジェンダーなんですが、グーテンベルク、ワードプレスの新しいエリーターが今度導入されます。これがどういう技術でできているかというのと、あとはそれを踏まえた上でグーテンベルクの機能を拡張していくにはどういう技術を使っていけばいいのかという話をします。今日はグーテンベルクでワードプレスがどう変わるかとか、グーテンベルクに回る。ワードプレス開発者はどう備えるかという話は、僕は正直あまりわかってなくてできないので、グーテンベルクの技術的な側面だけを集中的にお話しようと思います。よろしくお願いします。グーテンベルクのギッドハブリポジトリなんですけど、ここでグーテンベルクのソースコードのうち、どれくらいの割合がどの言語で占められているかというのが見ることができます。グーテンベルクは今はちょっと後で、今後ワードプレス5.0にあったらプラグインではなくなるかもしれないんですけど、今のところワードプレスプラグインとして実装されています。ただし、ワードプレスプラグインなんだけど、ほとんどのコードがJavaScriptでできています。グーテンベルクが使っているJavaScriptという言語なんですけど、ちょっとこれおさらいしていきます。ウェブブラウザで動く唯一のプログラミング言語がJavaScriptです。JavaScriptというのは、エクマインターナショナルという団体が使用を作っていて、この使用のことをエクマスクリプトと呼びます。ES3とかES5とか、結構聞いたことある方もいらっしゃると思うんですけど、2015年以降はES6というバージョンだったのが、2015という名前になって、以降はES2015、2016、2017で最新が2018です。このエクマスクリプトなんですが、裏側でこの使用が、裏側でエクマスクリプトの使用策定にはプロセスがあって、まずこういう使用をやってみようという提案があり、それを実際にブラウザで、例えばChromeとかFirefoxとかで実際に実装してみて、それがこの使用でいけるねってなったら、本格的に標準化というか、ちゃんとした使用として策定されるというプロセスにやってます。なのでES2018、今年の6月に出たバージョンなんですけど、この使用の機能が最新ブラウザであれば、基本的に全部動作します。ただし、IE11、多分日本でもまだシェア2割くらい残ってると思うんですけど、これに関しては完全にバージョンが止まっているので、ES5でしか動きません。なので、ちょっとウェブ開発においてはIE11で色々ちょっと辛いところがあるんですけど、その話はおいておきます。ジャバスクリート開発で、ちょっと前だとJQueryを使ってJQueryプラグインを入れてとか、そういうつく開発が多かったと思うんですけど、最近はもうちょっと細かいライブラリをインストールして使うような開発が多くなっています。具体的にはNPMというパッケージマネージャーがあって、これを使ってライブラリの管理をするのが、最近のジャバスクリート開発の一般的な開発方法にやってきています。その時にNPMはパッケージJSONというファイルがあるので、このファイルを見ることでグルテンベルクがどういうライブラリを使っているかがわかります。どういうライブラリを使っているかがわかれば、だいたい全体的な仕組みが見えてくるので、まず最初にそこから見ていきます。グルテンベルクのパッケージJSON、ちょっとこれリンク貼ってるんですけど、実質は今表示しません。具体的にどういうライブラリを使っているかというと、まず一番重要なのがリアクトJSです。その他にも、ワードプレスを昔からJQueryを使っているので、JQueryもグルテンベルクの中でどれくらい使っているかは別として、Dependencies、動作に必要なライブラリには列挙されています。あとは、ワードプレスの独自JSライブラリも結構あって、その辺もアットワードプレスというネームスペースの下から参照できます。その他に開発時にどういうライブラリを使っているかというのでデブディペンデンシーズというのがあって、ここに先ほどちょっとお話しあったと思うんですけど、バベルとかウェブパックとかその辺のいろいろな開発用ライブラリがあります。まずリアクトJSから。リアクトJSでも、ウェブ開発やっている方は何かしら聞いたこともある方が多いと思うんですけど、フェイスブックが2013年だってな、その頃に出したUIライブラリで、今でも最も人気のあるJSライブラリの一つになっています。NPMでインストール、ダウンロードされた回数だと、Jqueryを抜いていて、1位かどうかちょっと自信がないんですけど、アンギュラーとかビュージェースとか他のJSフレームワークとかを含めても一番人気があるライブラリの一つです。ちょっとNPM、Jqueryだと、NPM関係なくCDNとかから使っている人も多いと思うんで、これを持ってリアクトが一番とは言い切れないんですけど、リアクトも最新というよりはデファクトになりつつあるライブラリかなと思っています。グウィテンベルクはちょっとうよ曲折あったんですけど、今はリアクトJSで作られています。リアクトJSにはどういう特徴があるかというと、例えばグウィテンベルクって触ったことのある方は結構もうすでにいらっしゃると思うんですけど、複雑なUIです。あれをJqueryで作るのはかなり大変なんですが、リアクトはコンポーネントという単位でフルマイト見た目をまとめて管理することができて、この辺はWebコンポーネンっていうまだブラウザで完全には実装されていない仕様を参考にした設計なんですけど、このコンポーネントという単位で、例えばブロック、弾楽とか画像とかそういうものをブロックという単位にまとめ、コンポーネントという単位にまとめることで開発の効率を上げているというか、メンテナンスしやすいコードにすることができます。リアクトJSのサンプルコード、ちょっとこれ、今までJavascriptを書いてきた方の中でもなんちゃこれって思う人も結構いると思うんですけど、まず使っている公文としてはES2015のクラス公文というものを使っています。これは使わなくてもいいんですけど、ちょっとサンプルコードを短くするために使っています。あともう一つ、最大の特徴が、これJavascriptなんですけど、この中にいきなりHTMLが出てきます。これを何と言うかというと、あれ、ちょっとこれ飛ばしますね。なんかちょっと割と細かい話なので。さっきみたいなJavascriptの中にHTMLを書く公文のことをJSXと呼びます。これはリアクト独自のもので他のフレーマークでもJSXを使えるものがあります。例えばViewJSとかJSXを使え、ライブラリを入れば使えます。JSXはHTMLが直接書けるというのが最大の特徴で、それ以外の点では普通のHTMLと同じ、あ、じゃない、Javascriptと同じです。どういうことかというと、なんかHTMLを出力する部分を覗いては普通の譜文とか、譜文とか訪文とか、Javascriptの行動を使って最終的なユーザーに見せるHTMLを組み立てていくことができるというところです。ただし、JSXはブラウザで直接実行できる行動にはなっていません。Facebookはブラウザとか作っていないので、これはブラザで動くようになる未来はないと思います。なので、これをブラザで動くJavascriptに変換する必要が出てきます。そこで登場するのが、このバベルというツールです。バベルというのは何をするかというと、JavascriptをJSXがJavascriptと言えるかちょっと微妙なんですけど、Transpireというある言語で書かれた言語というか、Javascriptの中で、例えば特性のバージョンから別のバージョンに変換するとか、変換処理を行うソフトウェアです。リアクトを使う場合、JSXを使うことが多いので、その場合はバベルを使ってJSXのコードをJavascriptに変換して最終的にユーザーに配信します。グレテンベルクでもバベルを使っています。JSXによるTranspireが実際にどのように行われるかというと、これがサンプルコードなんですけど、一番上がまずJSXで書いたコードです。この段階では普通のJavascriptの中にHTMLがいきなり書かれている状態になっています。これをバベルを使ってTranspireするとどうなるかというと、さっきのHTML、H1とかで囲まれている部分が、リアクトクリエイトエレメントという関数の呼び出しに変換されます。クリエイトエレメントの第一引数にタブの名前で、第2引数が特性で、今回はH1は何もないので塗るを渡しています。最後は中の本点で、ここにHello Worldとやっておくと、上のJSXのコードの同じ意味合いになります。なので、バベルがやってくれるのは、上のコード、下のコードに変換するということをやってくれます。あと、ちょっとグレテンベルクの違うところとしては、リアクトはクリエイトエレメントという関数を用意しているんですけど、これをさらにグレテンベルクではラップしていて、グローバル変数にグレテンベルクを使っていると、グローバルWindow.wpというところに、いろんなグレテンベルク用のライブラリが定義されています。その中のwpエレメントというのを使うと、通常のリアクトと同じクリエイトエレメントというAPIで、グレテンベルク用のクリエイトエレメント関数を呼び出すことができます。この辺ちょっと違いはあるんですけど、ほとんどリアクトのAPIと同じように使うことができます。クリエイトエレメント、JSXを使わなくても、実は手書きすることができます。ただ、こんな感じでネストしたJSXもクリエイトエレメントで表現できるんですけど、こんな感じで関数呼び出しをどんどんネストさせていくというかなり辛いコードになってしまうので、基本的にはこっちのJSXを使ったコードのほうが良い、メンテナンスしやすいかなと思っています。あとは、先ほど紹介方はウェブパックについて、ウェブパックって何かというと、モジュールシステムというものをIE11とかの古いブラウザでも動くようにするライブラリです。わかってると、セットで使うことが多いって書いてあるんですけど、これは何でかというと、ウェブパックはあるJSを別のファイルにまとめるということをしてくれるツールで、それによっていろんなことが実現できる。そのうちの一つにバベルによるトランスファイルもあります。モジュールシステム、先ほどはウェブパックを使う理由としてモジュールシステムが実現できるというのが出たんですが、そもそも今までのジャバスクリート開発って、今までのJquery時代のジャバスクリート開発は基本的にライブラリがグローバルに定義されていて、例えばJqueryであればグローバル変数としてDALAとかJqueryとかが定義されていて、それを使ってプログラムを書いていくというスタイルだったと思うんですけど、そうではなくてグローバルには定義しない。代わりに外から読み込んで必要なものだけを使うというそういう使用がモジュールシステムというものです。PHPを書いたことになる人なら、リクワイヤーとかインクルードとかって使っておくとあると思うんですけど、それと同じものです。ちょっとだけ違うのは、ES2015のモジュールシステムはインポートという読み込み分だけじゃなくて、Xportという、このファイル方はこの関数が使えるよとか、そういう、この関数、外に出すものを宣言できるようになっています。それを除いてはほぼPHPのリクワイヤー、インクルードと同じです。Chromeとかの最新版ではもう動くようになっています。ただしIE11では動かないのでWebpackを使って動作するように変換する必要があります。モジュールバンドラ Webpackというのは複数のJSファイルを一つのJSファイルにまとめる機能を持っているツールです。先ほどそのグローバルに定義したJavaScriptではなくて、ローカルというか各ファイルから自分が使うファイルを呼び出すような方式になるというお話をしたんですけど、これ一つのJSファイルにまとまることで、そのJSファイルの中で、例えばバンドル.jsというものの中にJQueryとかリアクトとかオーメントJSとかいろんなものが入っていれば、そのファイルの中から探してくれば、今は自分のプログラムに必要なライブラリーはどれかというのを解析することができるので、モジュールバンドラがモジュールシステムの土台になっている人にはそういう理由です。このモジュールバンドラ、ウェブパックのグテンベルクでは使っています。あと、これはちょっと若干マニアックな話なんですけど、リアクト開発で、フラックスとかリラックスとかというライブラリーとか、アーキテクチャパターンのお話を聞いたことがある方もいると思うんですけど、グテンベルクのプラグニン開発に関して言えば、フラックスは必須ではないです。グテンベルク自身はリラックスとかかなりヘビンに使っているんですが、僕も一つ書いてみたんですけど、そんなに幸福な状態を持たないのであれば、そもそもフラックスとかリラックスはいらないので、最初はまずリアクトに集中して学習してみるといいかなと思います。このまで、グテンベルクがどういう技術を使っているかというお話を、一回まとめると、グテンベルクってワードプレスプラグニン、今はワードプレスプラグニンになっていて、NPMでライブラリー管理しています。リアクトJSを使ってUIを作っていて、VabellとかWebpackを使って、まずVabellを使ってリアクトを裏側で動くようにして、Webpackを使ってモジュールシステム部下を動くようにしています。この辺の技術スタックを自分でもある程度使いながら、グテンベルクのプラグニンを開発していく必要があります。ただし、VabellとかWebpackとか、そらいしたことがあるからわかると思うんですけど、結構難しいです。僕はプラグニン作ってて思ったのは、最低限に知る必要があるのはリアクトと、グテンベルクのAPI、この2つだけで、WebpackとかVabellのビルドの仕組みとかは、少なくとも今、ツールに任せることができるようになっています。具体的に言うと、クリエイトグーテンブロックとか、いくつかツールも出てきているんですけど、コマンド一発でグーテンベルクの開発環境、VabellとかWebpackとかの開発環境を全部作ってくれるツールが出てきています。なので最初は、まずクリエイトグーテンブロックとか、その辺のツールを使って開発環境をセットアップして、リアクトに集中して、最初覚えていくといいかなと思っています。リアクトは幸いも結構、リリースされたから時間が経っているので、学習用のリソースも揃っているし、APIの変更も最近だんだん、トラスティックのものが減ってきているので、学習するタイミングとしては良いかなと思っています。続いて、グーテンベルクのプラグインをどうやって作っていくかというところを話します。グーテンベルクって使ったことのある方ならわかると思うんですけど、ブロックというものを組み合わせることで、最終的なHTMLを組み上げていきます。このブロックを自分でも登録することができるようになっています。グーテンベルクにはブロックAPIというものがあり、コアのブロック、例えばパラグラフとかイメージとかのブロックAPIを使って、グーテンベルクにこういうブロックがあるよというのを認識させています。このブロックは結構実装参考にあるので、一回眺めてみるの。実際にブロックってどうやって書くのって、言うとこんな感じで、ちょっとインポートはさっきお話した、外からヘローブロックという色を読み込んでいるところなんですけど、まずブロックを登録するには、ウィンドウの下にあるWPというグログラ変数からブロックスのレジスターブロックタイプという関数を呼び出します。こいつに、第1引数は名前で、第2引数でブロックとしての動作を定義します。アトリビューツっていうのは、もうちょっとお話しするんですけど、ブロックが持つメタデータです。例えば、段落の中央寄せなのか、なんか右寄せなのか、そういうデータとかです。あとブロックの特に重要なAPIとしては、エディットと生物っていうやつがあります。エディットはブロックの初回表示。先ほどのこれで言うところも、例えばこの辺を押した時にブロックがここに追加されるんですけど、その時の表示を決める関数です。それだけではなくて、データベースに既にブロックが保存されている時は、データベースに保存されているデータからブロックを復元するっていうこともします。なので、このエディットがまず一つ重要な関数です。もう一つ重要な関数として生物っていうのがあって、生物っていう関数が返した値がデータベースに保存されます。なので、最終ライフサイクルのお話。ちょっと問わすんですが、ブロックのライフサイクルというお話があり、エディットで最初の初期状態を表示します。それからユーザーがブロックの中に、例えばバラグラフであれば文字を書き込んでいったら色を設定したりして、最終的にユーザーが保存ボタンをポチッと押すとそのデータがデータベースに保存されます。こういう風な流れでブロックのデータは編集されて保存されていきます。このブロックの実際の実装に関しては完全にリアクトです。ちょっとだけ違うのは、ブロックの中にアトリビュースとかあるんですけど、この辺はそんなに深い話では、今日はちょっと深い話はしません。ブロックはほぼリアクトで作ります。この会場にいる方は、割とエンジニア的な方が多いと思うので、関心があると、記事データの保存形式についてお話します。先ほどデータベースに保存されてお話したんですけど、具体的にどうやって保存されるかというと、ワードプレスの記事データは、WP Postというテーブルのコストコンテントという絡みに保存されます。これは今のクラシックエディターでも同じです。ただし、グーテンペリクの場合は、通常のHTMLに加えてメタデータをコメントに埋め込みます。具体的にどうなるかというと、ちょっとこれ、この設計が良いのかというのは、いろいろな議論があったんですけど、こんな感じでブロックであることを区切るコメントが入って、そしてこれとか画像のブロックなんですけど、画像の実際のURLは、この辺にJSONでURLがはにあるらみたいな感じ埋め込まれてます。こんな感じのデータが、Postコンテントに保存されます。ただし、これはユーザーに最終的に配信されるHTMLではなくて、ユーザーに配信される段階では先ほどのコメントとかは全部消えます。あとはメタデータとかも取り除かれるし、メタデータが表示に必要であれば、それを使って描画されます。最終的なHTMLはこんな感じの普通のクリーンなHTMLになります。記事の描画に関してはサーバーサイド、PHPだけが使われて、リアクトは記事の編集画面には使うんですけど、記事の実際の表示、レンダリングには使いません。ただしJSOベッド使うことが可能です。ライフサイクラ、先ほど話したのベッドがします。アトリビューツっていうのがグテメルクのちょっと難しいところで、例えば先ほどエディットで初期状態を復元する必要があるって話をしたんですけど、HTMLのコンテンツだけじゃなくて、そのコンテンツを表示するために必要なデータを全部エディットで使えるような形でメタデータとして保存しておく必要があります。その辺のAPIがアトリビューツとセッタートリビューツというもので、アトリビューツで定義した属性はセッタートリビューツで定義することができて、最終的にアトリビューツは、セーブのタイミングでデータベースにJSOのメタデータとしてコメントの中に埋め込まれて保存されます。このアトリビューツの定義がグテンベルフのブロック開発の気もかなと思っていて、たぶん、いろんなデータを詰め込みすぎると、記事が重くなったりすることになってしまうし、逆にデータが足りないと、ちゃんと復元できなくてブロックが壊れちゃうとか、そういうことが実際開発していておきました。あとは、ちょっとこれはプラグミンを選ぶときに、自分でプラグミン作るときも重要なんですけど、プラグミンを選ぶときにも重要な概念として、静的ブロックと動的ブロックというものがあります。静的ブロックというのは先ほどのセーブのタイミングで、全部コンテンツが決まります。この静的ブロックは一度保存されたら、それ以降は表示、ちゃんとできるのは保証されているので、そんなに悩むことはないんですけど、もう一つは、動的ブロックというのがあって、これは、例えば現在住屋を表示するブロックとかだと、そもそもセーブのタイミングが決まらないので、実際に記事を表示するタイミングでPHPで、現在住屋を取得して表示する必要があります。そういう機能を持つ動的ブロックというものがあって、動的ブロックは注意が必要なのが、プラグミンがアインストールされると動かなくなってしまう。しかも表示も崩れる可能性があるというところですね。なので、プラグミンを導入するときに、ブロックを提供してくれるプラグミンを導入するときには、それが動的ブロックだったら、結構プラグミンと一連卓象になる可能性があるというのは、認識しておく必要があるかなと思っています。ちょっとこの辺、先に話しちゃいましたね。プラグミンが提供しているブロックを使った後に、そのプラグミンをアインストールしてはどうなるかというと、これは僕が個人的に作ったアビリエイトリンクを貼るブロックのアインストールされているときの状態なんですけど、こんな感じでクラシックブロックというものに負けます。このクラシックブロックって何かというと、通常のブロックとしての機能はなくて、クラシックエディターのテキストを編集みたいな感じで、HTMLを編集することができるだけのブロックになります。なので最悪でもこのクラシックブロックに負けるので、特典のプラグミンはアインストールしたらいろんなものが壊れるということは、そんなにないんですけど、動的ブロックだと壊れる可能性があります。そこだけちょっと注意が必要です。あとは、ツイッターの埋め込みとかって、ジャバスクリートも使ってるんですけど、その辺は確実に壊れるので、その辺ちょっとどのプラグミンを使うかというのは、若干慎重な考慮が必要かなと思っています。で、グッテンベルグ、もうこれ最後のスライドなんですけど、グッテンベルグプラグミン、プラグミン書いたことあるかとはわかると思うんですけど、これがプラグミンのインデックスPHPとか、エントリポイントになるPHPファイルです。ここにアドアクションっていう関数を読んで、新しく追加されているフックとして、延期ブロックエディターアセットっていうのがあるので、ここに自作したプラグミンのブロックの発想書いて、ちょっとこの辺あんまり覚えてないんですけど、このブロックが使うAPIとかを定義して、書いておくと、このJSをグッテンベルグを読み込んでくれて、自分が書いたプラグミン、自分が書いたブロックが、グッテンベルグの上で呼び出し感動になります。で、ちょっと早いんですが、まっぽめです。グッテンベルグ、様々なジャカスクリートライブレイで実装されています。で、この辺は実は、ワードプレスの開発だとJQueryを使うことが多いと思うんですけど、ウェブアプリケーションの開発では、割と定番に塗ってきているような技術で実装されています。なので、ウェブのフロントエンドの定番の技術を身につけることで、グッテンベルグの対応プラグミンを作っていくことができます。で、最後にちょっと引用です。これは2015年のワードキャンプUSだと思うんですけど、そこでマットマリオメングっていうワードプレスの創設者の人がいったワードプレス開発者に今後求めることとして、ラウン・ジャカスクリートディープリーって言っていて、ワードプレスもっとジャカスクリートを使っていくから、みんなもジャカスクリートを学んで、すごく作っていこうって、そういうお話です。以上で僕のお話は終わりです。ご清聴ありがとうございました。お移りたいと思います。会場の皆様で、質問がある方は拒否をお願いいたします。私はマイクを持ってそちらに伺いますので、拒否をお願いいたします。先ほど保存されたデータ、確実なブロックでデータが保存されて、コメントの形で展開されていました。最終的にあれを書き出す段階で、パースというか、報告解析がされて、それぞれのブロックに変換される、ブロックの本来の表示になると思うんですけども、そのデータというのは何回か試したのか見たんですが、スタイルシートは使っているものがミニファイされるって、一つのファイルになったんですけど、HTMLについては、キャッシュされるとかいうことはないのでしょうか。毎回、対応のブロックが処理されたらかなり時間がかかって思ってるんですか。正直、わからない。おそらく今の実装ではキャッシュとかはしてないと思います。なので、コンテンツが多いと今のワードプレスよりも新しいグテンベルクのコンテンツの方が、分量が多い時に病化が遅くなってしまう可能性はあるかなと。その辺はグテンベルクの、特にサーバーサイドの行動を見てみれば今の段階ではわからないです。