WordPress 플레이그라운드 및 WebAssembly로 브라우저 내 WordPress 환경 빌드

PHP를 기반으로 하며 WebAssembly를 사용하여 브라우저에서만 실행되는 전체 WordPress

Thomas Nattestad
Thomas Nattestad

WordPress 플레이그라운드를 처음 보면 다채로운 배경을 제외하고는 평범한 사이트처럼 보일 수 있습니다. 그와는 전혀 다릅니다. 실제로 보고 있는 것은 PHP 및 데이터베이스를 비롯한 전체 WordPress 기술 스택이 브라우저에서 직접 실행되는 것입니다.

이 게시물에서는 Adam Zieliński (WordPress 플레이그라운드 책임자)와 Thomas Nattestad(V8 제품 관리자)가 다음을 살펴봅니다.

  • WordPress 개발자가 WordPress 플레이그라운드를 활용하는 방법
  • 내부 작동 방식
  • WordPress의 미래에 미치는 영향

설치 없이 WordPress를 사용하고, 앱에 삽입하고, JavaScript로 제어할 수도 있습니다.

playground.wordpress.net에 삽입된 WordPress를 무료로 사용하고 맞춤설정할 수 있습니다. 이 사이트는 브라우저에만 있으므로 다른 사용자가 방문할 수 없으며, 따라서 비용을 지불해야 하는 클라우드 인프라와 지원이 없습니다. 또한 임시 조치입니다. 페이지를 새로고침하면 삭제됩니다. 프로토타입 제작, 플러그인 사용해 보기, 아이디어 빠르게 탐색을 위해 이러한 사이트를 원하는 만큼 가져올 수 있습니다.

내장된 PHP 및 WordPress 버전 전환 도구를 사용하여 다양한 환경에서 코드를 테스트하는 데도 사용할 수 있습니다.

phpinfo 페이지를 엽니다.

WordPress 플레이그라운드는 WordPress를 사용하는 완전히 새로운 방법입니다. 하지만 이 도구의 모든 기능을 사용하려면 앱에 포함해야 합니다. WordPress 플레이그라운드를 <iframe>에 삽입하고 쿼리 매개변수 API를 사용하여 구성하는 것이 가장 쉽습니다. 공식 쇼케이스가 바로 이 역할을 합니다. 예를 들어 펜던트 테마Coblocks 플러그인을 선택하면 삽입된 iframe이 https://playground.wordpress.net/?theme=pendant&plugin=coblocks를 가리키도록 업데이트됩니다.

WordPress 플레이그라운드 쇼케이스

iframe은 간편하게 시작할 수 있는 방법이지만 기본 구성 옵션으로 제한됩니다. 그보다 더 많은 기능이 필요한 경우 더 강력한 다른 API가 있습니다.

WordPress 플레이그라운드 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를 사용할 수 있습니다. 아담은 전자를 사용하여 이 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 플레이그라운드는 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 플레이그라운드에서는 처음부터 빌드해야 했습니다. 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 플레이그라운드는 네이티브 SQLite 드라이버와 함께 PHP를 제공하고 SQLite를 사용합니다.

하지만 WordPress를 다른 데이터베이스에서 실행하려면 어떻게 해야 하나요?

백그라운드에서 공식 SQLite 데이터베이스 통합 플러그인이 모든 MySQL 쿼리를 가로채 SQLite 방언으로 다시 작성합니다. 2.0 출시에는 SQLite의 WordPress가 WordPress 단위 테스트 모음의 99% 를 통과할 수 있도록 하는 새로운 WordPress 플레이그라운드 기반 변환 레이어가 포함되어 있습니다.

웹 서버가 브라우저 내부에 있습니다.

일반 WordPress에서는 링크(예: 블로그)를 클릭하면 원격 백엔드에 HTTP 요청을 시작하여 blog 페이지를 가져옵니다. 하지만 WordPress 플레이그라운드에는 원격 백엔드가 없습니다. 이 앱에는 모든 발신 요청을 가로채서 별도의 웹 워커에서 실행되는 브라우저 내 PHP 인스턴스에 전달하는 서비스 워커가 있습니다.

리소스 wp-admin을 가리키는 iframe으로 시작하는 흐름 다이어그램. 이 iframe의 호출은 서비스 워커에 의해 가로채지고, 작업자 스레드에서 렌더링되며, 궁극적으로 브라우저 내 서버에 의해 WordPress 응답으로 변환됩니다.

WebSocket을 통해 네트워킹이 지원됩니다.

네트워킹의 경우 WebAssembly 프로그램은 JavaScript API를 호출하는 것으로 제한됩니다. 이는 안전 기능이지만 문제점도 있습니다. JavaScript에서 사용 가능한 상위 수준 비동기 API를 사용하여 PHP에서 사용하는 하위 수준 동기 네트워킹 코드를 지원하려면 어떻게 해야 하나요?

WordPress 플레이그라운드의 경우 WebSocket to TCP 소켓 프록시, Asyncify, php_select와 같은 심층 PHP 내부 패치가 필요합니다. 복잡하지만 보상이 있습니다. Node.js 타겟팅 PHP 빌드는 웹 API를 요청하고, Composer 패키지를 설치하고, MySQL 서버에 연결할 수도 있습니다.

WordPress는 브라우저보다 더 많은 위치에서 사용할 수 있습니다.

이제 WordPress를 WebAssembly에서 실행할 수 있으므로 Node.js 서버에서도 실행할 수 있습니다. 동일한 V8 엔진을 사용합니다. 물론 StackBlitz를 사용하면 브라우저에서 Node.js를 직접 실행할 수도 있습니다. 즉, WebAssembly로 컴파일된 WordPress 및 PHP를 실행하고, Node.js에서 실행할 수 있으며, Node.js도 WebAssembly로 컴파일되어 브라우저에서 실행됩니다. WebAssembly는 서버리스 공간에서도 인기가 급증하고 있으며 향후 이 인프라에서도 실행될 수 있습니다.

앞으로는 설정이 필요 없는 양방향 공동작업 WordPress 앱이 등장할 수 있습니다.

모든 설정이 완료된 상태에서 바로 빌드할 수 있는 코드 편집기로 바로 이동할 수 있다고 상상해 보세요. 간단한 링크를 공유하고 Google Docs와 같이 멀티플레이어 수정 세션을 시작할 수도 있습니다. 완료되면 클릭 한 번으로 로컬에 아무것도 설치하지 않고도 다양한 호스팅 서비스에 작품을 원활하게 배포할 수 있습니다.

이 정도는 시작에 불과합니다. 대화형 튜토리얼, 실시간 플러그인 데모, 스테이징 사이트, 에지 서버의 분산형 WordPress, 휴대전화에서 플러그인 빌드 등이 표시될 수 있습니다.

미래는 흥미롭고 여러분도 그 일부가 될 수 있습니다. 여러분의 아이디어와 참여는 WordPress 플레이그라운드의 원동력입니다. GitHub 저장소를 방문하고 #meta-playground WordPress.org Slack 채널에서 인사말을 전해 주세요. adam@adamziel.com으로 언제든지 에담에게 문의해 주세요.