WordPress Playground と WebAssembly でブラウザ内の WordPress エクスペリエンスを構築

WebAssembly を使用してブラウザでのみ動作する PHP を利用した完全な WordPress

Thomas Nattestad
Thomas Nattestad

初めて WordPress プレイグラウンドを見たとき、カラフルな背景以外は普通のサイトのように見えます。それだけではありません。実際にご覧になっているのは、PHP とデータベースを含む WordPress 技術スタック全体であり、ブラウザで直接実行されます。

この投稿では、Adam Zieliëñski 氏(WordPress Playground のリーダー)と Thomas Nattestad 氏(V8 担当プロダクト マネージャー)が、次のトピックを取り上げます。

  • WordPress デベロッパーとして WordPress Playground を活用する方法。
  • 仕組み
  • WordPress の未来にとっての意味

WordPress をインストールせずに使用、アプリへの埋め込み、JavaScript での管理も可能

playground.wordpress.net に埋め込まれた WordPress は、無料で使用およびカスタマイズできます。このサイトは完全にお使いのブラウザのみで動作しているため、クラウド インフラストラクチャやサポートの料金は発生しません。これは一時的なものでもあります。ページを更新するとすぐに消えます。プロトタイピング、プラグインのテスト、アイデアの迅速な検討のために、これらのサイトを必要な数だけ取得できます。

また、組み込みの PHP と WordPress のバージョン スイッチャーを使用して、さまざまな環境でコードをテストすることもできます。

phpinfo ページをご覧ください。

WordPress Playground は、まったく新しい WordPress の使い方です。ただし、その機能を最大限に活用できるのは、アプリに WordPress Playground を含めることだけです。WordPress Playground を <iframe> に埋め込み、クエリ パラメータ API を使用して構成するのが簡単な方法です。公式ショーケースが行います。たとえば、Pendant テーマCoblocks プラグインを選択すると、埋め込み iframe が https://playground.wordpress.net/?theme=pendant&plugin=coblocks を参照するように更新されます。

WordPress プレイグラウンド ショーケース。

iframe は簡単に開始できる方法ですが、基本的な設定オプションのみに限定されています。それ以上の必要がある場合は、より強力な API を使用します。

WordPress Playground の JavaScript クライアントにより、埋め込みサイトを完全に制御できます。

@wp-playground/client npm パッケージから入手できる完全な API を使用して、ファイル システムや PHP を含む WordPress サイト全体を制御できます。次の例はその使用方法を示しています。その他の例については、インタラクティブなチュートリアルをご覧ください。

import {
  connectPlayground,
  login,
  connectPlayground,
} from '@wp-playground/client';

const client = await connectPlayground(
  document.getElementById('wp'), // An iframe
  { loadRemote: 'https://playground.wordpress.net/remote.html' },
);
await client.isReady();

// Login the user as admin and go to the post editor:
await login(client, 'admin', 'password');
await client.goTo('/wp-admin/post-new.php');

// Run arbitrary PHP code:
await client.run({ code: '<?php echo "Hi!"; ?>' });

// Install a plugin:
const plugin = await fetchZipFile();
await installPlugin(client, plugin);

WordPress がなくても WebAssembly PHP を使用できます

WordPress のプレイグラウンドはモノリスではありません。WebAssembly PHP は WordPress とは別にリリースされており、個別に使用することもできます。ウェブの場合は、バンドルサイズを低く抑えるために最適化された @php-wasm/web npm パッケージを使用できます。Node.js では、より多くの PHP 拡張機能を提供する @php-wasm/node を利用できます。Adam は前者を使用して、こちらの WP_HTML_Tag_Processor チュートリアルにインタラクティブな PHP スニペットを追加しました。使い方を以下にご紹介します。

import { PHP } from '@php-wasm/web';
const php = await PHP.load('8.0', {
  requestHandler: {
    documentRoot: '/www',
  },
});

// Create and run a script directly
php.mkdirTree('/www');
php.writeFile('/www/index.php', `<?php echo "Hello " . $_POST['name']; ?>`);
php.run({ scriptPath: '/www/index.php' });

// Or use the familiar HTTP concepts:
const response = php.request({
  method: 'POST',
  relativeUrl: '/index.php',
  data: { name: 'John' },
});
console.log(response.text); // Hello John

ここで、これはどのように機能するのかを考える必要があります。お問い合わせいただきありがとうございます。 その内部の仕組みを見ていきましょう準備はいいですか?

内部には WebAssembly PHP、SQL トランスレータ、ブラウザ内サーバーがあります。

PHP は WebAssembly バイナリとして実行

PHP は、ブラウザだけですぐに利用できるわけではありません。WordPress Playground は、Emscripten を使用して WebAssembly 用の PHP インタープリタをビルドする専用パイプラインを開発しました。標準 PHP のビルドはそれほど複雑ではありません。ここで関数のシグネチャを調整し、構成変数を強制適用して、いくつかの小規模なパッチを適用するだけです。ご自身で構築する手順は次のとおりです。

git clone https://github.com/WordPress/wordpress-playground
cd wordpress-playground && npm install
# Below, you can replace "8.2" with any other valid PHP version number.
npm run recompile:php:web:8.2

ただし、標準の PHP ビルドはブラウザであまり役に立ちません。サーバー ソフトウェアである PHP には、リクエスト本文の受け渡し、ファイルのアップロード、php://stdin ストリームへの入力を行う JavaScript API がありません。WordPress Playground はゲームを一から構築する必要がありました。WebAssembly バイナリには、C で記述された専用の PHP API モジュールと、writeFile()run() などのメソッドを公開する JavaScript PHP クラスが含まれています。

すべての PHP バージョンは単なる静的な .wasm ファイルであるため、PHP のバージョン スイッチャーは実際にはかなり退屈です。これは単に、ダウンロードをブラウザに指示するだけです。たとえば、php_8_2.wasm ではなく php_7_3.wasm と指示します。

データベースは SQL 変換レイヤでサポートされている

WordPress には MySQL が必要です。ただし、ブラウザで実行可能な MySQL の WebAssembly バージョンはありません。そのため、WordPress Playground には PHP にネイティブ SQLite ドライバが付属しており、SQLite を使用しています。

しかし、WordPress を別のデータベース上で実行するにはどうすればよいのでしょうか。

舞台裏では、公式の SQLite Database Integration プラグインがすべての MySQL クエリをインターセプトし、SQLite 言語で書き換えます。2.0 リリースには、WordPress のプレイグラウンド情報に基づく新しい変換レイヤが搭載されています。これにより、SQLite 上の WordPress が WordPress 単体テストスイートの 99% に合格するようになります。

ウェブサーバーはブラウザ内にあり、

通常の WordPress では、ブログなどのリンクをクリックすると、リモート バックエンドへの HTTP リクエストが開始され、blog ページを取得します。ただし、WordPress Playground にはリモート バックエンドがありません。すべての送信リクエストをインターセプトし、別の Web Worker で実行されているブラウザ内 PHP インスタンスに渡す Service Worker があります。

リソース wp-admin を参照する iframe で始まるフロー図。その呼び出しは Service Worker によってインターセプトされ、ワーカー スレッドでレンダリングされ、最終的にブラウザ内サーバーによって WordPress レスポンスに変換されます。

ネットワーキングは WebSocket を介してサポートされている

ネットワーキングに関しては、WebAssembly プログラムは JavaScript API の呼び出しに限定されています。これは安全機能ですが、課題も伴います。PHP で使用される低レベルの同期ネットワーク コードを、JavaScript で利用可能な高レベルの非同期 API とともにどのようにサポートするか。

WordPress のプレイグラウンドの場合、WebSocket から TCP ソケットへのプロキシ、Asyncifyphp_select などのディープ PHP 内部にパッチを適用します。複雑だけど、報酬はある。Node.js をターゲットとする PHP ビルドでは、ウェブ API のリクエスト、Composer パッケージのインストール、MySQL サーバーへの接続を行うことができます。

WordPress はブラウザ以外の場所でも利用できる

WordPress を WebAssembly で実行できるようになったため、同じ V8 エンジンである Node.js サーバーでも実行できるようになりました。StackBlitz ではもちろん、ブラウザで Node.js を直接実行することもできます。つまり、WebAssembly にコンパイルされた WordPress と PHP を Node.js で実行し、これもブラウザ内で実行される WebAssembly にコンパイルできます。また、WebAssembly はサーバーレス分野でも爆発的に普及しており、将来的には、そのインフラストラクチャでも実行される可能性があります。

将来的には、セットアップ不要のインタラクティブな WordPress アプリが登場するかもしれません

すぐにコードエディタを開いて、すべての設定が完了したので、すぐにビルドを始められるところを想像してみてください。さらに、Google ドキュメントなどのシンプルなリンクを共有して、マルチプレーヤー型ゲームの編集セッションを開始することもできます。インストールが完了したら、1 回クリックするだけで、作成したものをさまざまなホスティング サービスにシームレスにデプロイできます。ローカルに何もインストールする必要はありません。

これはほんの一例です。インタラクティブなチュートリアル、プラグインのライブデモ、ステージング サイト、エッジサーバー上の分散型 WordPress、スマートフォン上でのプラグイン構築などを行う場合があります。

未来はとてもエキサイティングで、あなたもその一翼を担えるでしょう。皆さんのアイデアや投稿は WordPress Playground の原動力ですGitHub リポジトリにアクセスし、#meta-playground WordPress.org Slack チャンネルで話しかけてください。また、Adam(adam@adamziel.com)までお気軽にご連絡ください。