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

PHP をベースとした完全な WordPress が、WebAssembly を使用してブラウザでのみ実行される

Thomas Nattestad
Thomas Nattestad

WordPress Playground を初めて見ると、カラフルな背景を除けば、普通のサイトのように見えます。実際に表示されているのは、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 を <iframe> に埋め込み、クエリ パラメータ API を使用して構成することです。公式ショーケースは、その役割を果たします。たとえば、Pendant テーマCoblocks プラグインを選択すると、埋め込まれた iframe が更新され、https://playground.wordpress.net/?theme=pendant&plugin=coblocks を参照するようになります。

WordPress Playground のショーケース。

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 Playground はモノリシックではありません。WebAssembly PHP は WordPress とは別にリリースされており、個別に使用することもできます。ウェブの場合は、バンドルサイズを小さくするように最適化された @php-wasm/web npm パッケージを使用できます。Node.js では、より多くの PHP 拡張機能を提供する @php-wasm/node を利用できます。アダムは前者を使用して、こちらの 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 を使用して PHP インタープリタを WebAssembly にビルドするための専用のパイプラインを開発しました。標準の 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 Playground を活用した新しい変換レイヤが提供されます。これにより、SQLite 上の WordPress は WordPress 単体テストスイートの 99% に合格できるようになります。

ウェブサーバーがブラウザ内に存在する

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

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

ネットワーキングは WebSocket でサポートされています。

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

WordPress Playground の場合、WebSocket から TCP ソケット プロキシ、Asyncifyphp_select などの PHP 内部へのパッチ適用が含まれます。複雑ですが、報酬があります。Node.js をターゲットとする PHP ビルドは、ウェブ API をリクエストしたり、コンポーザー パッケージをインストールしたり、MySQL サーバーに接続したりできます。

WordPress はブラウザ以外にも多くの場所で使用できます

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

将来的には、セットアップ不要でインタラクティブなコラボレーション アプリが WordPress で利用できるようになるかもしれません。

コードエディタに直接ジャンプして、すべての設定が完了した状態ですぐにビルドを開始できるとしたらどうでしょう。簡単なリンクを共有して、Google ドキュメントなどのマルチプレーヤー編集セッションを開始することもできます。作成が完了したら、1 回のクリックでさまざまなホスティング サービスにシームレスにデプロイできます。ローカルにインストールする必要はありません。

以上はほんの一部です。インタラクティブなチュートリアル、ライブ プラグイン デモ、ステージング サイト、エッジサーバー上の分散 WordPress、スマートフォンでのプラグイン作成などが行われる予定です。

未来はワクワクするもので、あなたもその一員になれます。皆様のアイデアと貢献は WordPress Playground の酸素です。GitHub リポジトリにアクセスし、#meta-playground WordPress.org Slack チャンネルで挨拶してください。また、Adam まで adam@adamziel.com までお気軽にお問い合わせください。