GutenbergはReactをどのように利用しているか

WordPressの新しいエディタGutenbergは紆余曲折を経てReactでの開発を続けており、2018年5月ぐらいのリリースを目指しているようだ。新しいAPIも整備されつつあり、カスタムフィールド製造業界を震撼させたメタボックスも新しいAPIが整備されつつある。

さて、いずれにせよ、投稿編集画面に新しい時代が訪れることは間違いないので、それをどのように作っているのかについて知っておくのは悪いことではない。

Reactに関する前提知識

今回の記事ではあまり詳細に立ち入らないが、Reactは昨今のJavascript開発を牽引するライブラリであり、2010年ごろのJavascript開発とは圧倒的に違っている。圧倒的に変わった点として、次のようなものがある。

  • npmを使ったパッケージ管理npm install というコマンドをなんでかよくわからないまま打たされている人も多いだろう。基本的には npm にホスティングされているライブラリを管理するコマンドだ。WordPressプラグインの公式リポジトリからプラグインをダウンロードするようなものだと思ってもらっていい。
  • Javascriptのトランスパイル。PHPはスクリプト言語なので実行時にソースコードを読み取るが、C言語やJavaはコンパイルを行って、実行形式のバイナリを作成する。最近のJavascriptは言語仕様の変化(ES2015, JSX)、実行環境の多様化(ブラウザ、NodeJSによるサーバサイド)などに対応するため、元のファイルを変換する処理を行うことが増えている。

決定的に異なるのは上記二点である。言語自体の新しい機能(アロー関数、Promise, Async/Await, JSXほか)もあるが、特に触れない。

そして重要なのは「これまでのWordPressはこうしたモダンJS開発の手法を取り入れていなかった」という点である。zipファイルをぽんとアップロードすればレンタルサーバーでも動くので、インストール時になにかコマンドを打ったりする必要もない。コアが利用するライブラリも、wp-includes/js フォルダ以下に同梱される形だった。

Gurenbergのnpm構成

さて、前述した通り、GutenbergはReactを利用しているため、上記のテクノロジーを取り入れている。ためしにGutenbergのリポジトリでnpmの設定ファイルである package.json を見てみると……

  • Reduxを採用しているようだ。となると、このReduxの概念を理解せずに拡張機能を作ることは難しそうである。
  • トランスパイルは webpack + babel で行なっている。

興味深いのは、依存するライブラリとして以下の指定があること。

{
  "@wordpress/a11y": "0.1.0-beta.1",
  "@wordpress/hooks": "1.0.1",
  "@wordpress/url": "0.1.0-beta.1"}
}

これらは実際にnpmjs.comにホスティングされており、WordPressの get_query_args をJSで再実装したものや、アクセシビリティ関連のものがまとまっている。これまで、WordPressではコアのソースを自前のSVNにホストするということにこだわってきたと思うのだが、今後は分散管理になるのだろうか。

Githubにドキュメントがまとまっている

さて、最近Gutenbergのことを心配する人が多いので、Gutenbergについて説明するプロジェクトページが用意されたのだが、実はGithubの各ディレクトリにはreadmeが整理されており、「これはなんなのか」「このコンポーネントはどうなっているのか」といったことについての説明がある。

editorディレクトリのreadmeより

これらのドキュメントは非常によくできているので、見てみるとよいだろう。

依存関係は名前空間で解決

さて、最近のJavascriptでは依存するライブラリを指定する機能がある。

// NodeJSのrequireで、uniqライブラリを読み込み
var unique = require('uniq');
var data = [1,2,3,3,3];
console.log(unique(data));
// -> [1,2,3]

// ES6のインポート文
import {unique} from "uniq";
var data = [1,2,3,3,3];
console.log(unique(data));
// -> [1,2,3]

// 使われる側
export function unique(data){
  // ここで一意にする
  return data;
}

多くの場合、webpackやBrowserifyによるトランスパイルの過程で外部に影響を与えない形で読み込まれ、パッケージングされる。

では、流行りのSPA(シングルページアプリケーション)ではなく、WordPressのように「プラグイン自体があったりなかったりする」「利用するかしないかはページごとにPHPの側で決める」という場合、どんな風に実装しているのだろうか。

これはメディアライブラリと同じく、wp名前空間以下に展開することで利用される。したがって、import文を書いたりするのではなく、wp_enqueue_script で依存関係を指定し、参照する形になりそうだ。ためしに、新しいカスタムブロックを追加する機能を見てみると……

( function( blocks, element ) {
  var el = element.createElement,
      source = blocks.source;
  blocks.registerBlockType( 'myplugin/random-image', {
    // ここに設定
  } );
})(window.wp.blocks, window.wp.element)

となっており、wp以下の変数を参照することでGutenbergのAPIにアクセスしている。もちろん、モダンなES2015以上やJSXで書きたい人にはそのためのサンプルが用意されている。

となると、あとは「プラグイン同士がバッティングする可能性は?」「プラグインやテーマが特定のライブラリを読み込んでいる場合、それは二重読み込みにならないの?」という疑問が湧いてくるが、これはいまのところ解決する方法は提示されていない。

まとめ

以上、概観ではあるが、Gutenbergがどのように動いているのかについて説明した。WordPressプロジェクトのうち、Gutenbergはもっともモダンなテクノロジーを採用しているものの一つなので、「中身どうなってんだろ」と見てみることは、今後のWordPress開発の行方を占う意味でも役に立つのではないだろうか。

なお、現在Capital Pでは Vue.JS と React によるWordPress開発がどんなものなのかをお見せしようとおもっているので、お楽しみに。

 

“GutenbergはReactをどのように利用しているか”への5件の反応

  • atachibana

    Gutenberg の全体像を浮かび上がらせる良い記事でした。特に最初に読者に説明する部分:

    >> 2010年ごろのJavascript開発とは圧倒的に違っている。圧倒的に変わった点として、次のようなものがある。
    >> npmを使ったパッケージ管理。
    >> Javascriptのトランスパイル。

    ここらの”流れ”が曖昧だったので、こうしてバシッとまとめていただけると助かります。
    最近、仕方なく JavaScript に手を出した人間としては、特に。続編も期待しています。

  • Ryo (@ryo511)

    > 「プラグイン同士がバッティングする可能性は?」
    > 「プラグインやテーマが特定のライブラリを読み込んでいる場合、それは二重読み込みにならないの?」

    – webpackを使っている
    – グローバル(windowオブジェクト)に変数やオブジェクトを露出していない

    という条件を満たしている限り、自分のプラグインが読み込んだライブラリが別のプラグインに影響を及ぼすことはありません。
    また、他のプラグインがグローバルに定義した変数も、ローカル変数でシャドウされるため、外部から影響を受けることはありません。
    グローバル汚染の問題が発生しそうなのは、babel-polyfill等のpolyfill系くらいかなと思います。

    問題は二重読み込みですね。同じライブラリを複数のプラグインが読み込んだ結果、JavaScriptの読み込み量が増えてしまう可能性があります。

    webpackを使ってグローバルを汚染しないのがお作法である、という流れになっていくといいなーと思ってます。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください