WordPress / wordpress-playground

Run WordPress in the browser via WebAssembly PHP
https://w.org/playground/
GNU General Public License v2.0
1.63k stars 250 forks source link

Add E2E test for running the Playground Client using browser native imports #1900

Open akirk opened 2 days ago

akirk commented 2 days ago

Problem

Introducing new dependencies to Playground can cause unintended consequences for browser native imports of the Playground Client. This results in errors like

Uncaught TypeError: The specifier “@wp-playground/storage” was a bare specifier, but was not remapped to anything. Relative module specifiers must start with “./”, “../” or “/”.

Which can be fixed by adding an importmap to unpkg.com but this can lead into a chain of further importmaps needed.

Working within in the Playground tooling these kind of changes go unnoticed but cause breakage. By adding an E2E test we can be warned about this and prevent that breakage from happening.

Background

Translate Live (e.g. https://translate.wordpress.org/projects/wp-themes/lms-education-courses/gl/default/playground/) loads the Playground client like this:

<script type="module">
import { startPlaygroundWeb, phpVars, setPluginProxyURL } from 'https://playground.wordpress.net/client/index.js';
import { compileBlueprint, runBlueprintSteps } from '@wp-playground/blueprints';
import { ProgressTracker } from '@php-wasm/progress';
// ...
</script>

For this to work, it additionally needs to specify an importMap like this:

<script type="importmap">
{
    "imports": {
        "@wp-playground/common": "https://unpkg.com/@wp-playground/common/index.js",
        "@wp-playground/blueprints": "https://unpkg.com/@wp-playground/blueprints/index.js",
        "@php-wasm/node-polyfills": "https://unpkg.com/@php-wasm/node-polyfills/index.js",
        "@php-wasm/scopes": "https://unpkg.com/@php-wasm/scopes/index.js",
        "@php-wasm/progress": "https://unpkg.com/@php-wasm/progress/index.js",
        "@php-wasm/logger": "https://unpkg.com/@php-wasm/logger/index.js",
        "@php-wasm/stream-compression": "https://unpkg.com/@php-wasm/stream-compression/index.js",
        "@php-wasm/universal": "https://unpkg.com/@php-wasm/universal/index.js",
        "@php-wasm/util": "https://unpkg.com/@php-wasm/util/index.js",
        "ini": "/wp-content/plugins/wporg-gp-playground/inc/routes/ini.js",
        "ajv": "/wp-content/plugins/wporg-gp-playground/inc/routes/ajv.js"
    }
}
</script>

The last two of these, ini and ajv are already short-circuited versions of the libraries because they themselves causes many dependencies that are not required to run it. Specifically:

https://translate.wordpress.org/wp-content/plugins/wporg-gp-playground/inc/routes/ajv.js

const ajv = function() {
}
ajv.compile = function() {
    return function() {
        return true;
    }
};
export default ajv;

and https://translate.wordpress.org/wp-content/plugins/wporg-gp-playground/inc/routes/ini.js which is a manual conversion to cjs.

bgrgicak commented 2 days ago

@psrpinto made a good point about the playground needing an "npm install playground" that contains everything you need. Today you are relying on the Remote package from Playground.WordPress.net, or self-hosting. Having it as an NPM package should prevent issues where Remote isn't compatible with the Client version you got from NPM. This would technically be npm install WordPress 🙂

I know there are size issues with remote because it has around 650MB of wasm, and WP asset files, but we could ship it with just the default version of PHP and WP.