diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11ab205380..59525b3c42 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -41,29 +41,29 @@ The following contributors merged PRs in this release:
### Tools
-- [ CLI ] Rename CLI binaries in `@php-wasm/cli` and `@wp-playground/cli`. ([#2441](https://github.com/WordPress/wordpress-playground/pull/2441))
+- [ CLI ] Rename CLI binaries in `@php-wasm/cli` and `@wp-playground/cli`. ([#2441](https://github.com/WordPress/wordpress-playground/pull/2441))
### Documentation
-- Updating Docusaurus version from 3.7 to 3.8. ([#2457](https://github.com/WordPress/wordpress-playground/pull/2457))
-- [Docs] Adding fixes to broken URLs. ([#2451](https://github.com/WordPress/wordpress-playground/pull/2451))
-- [Docs] Bump PHP version to avoid WordPress PHP version Warning. ([#2443](https://github.com/WordPress/wordpress-playground/pull/2443))
+- Updating Docusaurus version from 3.7 to 3.8. ([#2457](https://github.com/WordPress/wordpress-playground/pull/2457))
+- [Docs] Adding fixes to broken URLs. ([#2451](https://github.com/WordPress/wordpress-playground/pull/2451))
+- [Docs] Bump PHP version to avoid WordPress PHP version Warning. ([#2443](https://github.com/WordPress/wordpress-playground/pull/2443))
### PHP WebAssembly
-- Patch the premature "request in progress" semaphore release. ([#2455](https://github.com/WordPress/wordpress-playground/pull/2455))
+- Patch the premature "request in progress" semaphore release. ([#2455](https://github.com/WordPress/wordpress-playground/pull/2455))
### Bug Fixes
-- Re-enable Playground CLI tests. ([#2445](https://github.com/WordPress/wordpress-playground/pull/2445))
+- Re-enable Playground CLI tests. ([#2445](https://github.com/WordPress/wordpress-playground/pull/2445))
### Various
-- Add check for SQLite driver missing in target folder. ([#2440](https://github.com/WordPress/wordpress-playground/pull/2440))
-- Adding CLI reference to Playground README. ([#2433](https://github.com/WordPress/wordpress-playground/pull/2433))
-- Adding Gujarati Intro documentation. ([#2450](https://github.com/WordPress/wordpress-playground/pull/2450))
-- Bump WordPress old version demo to version 6.2.1. ([#2460](https://github.com/WordPress/wordpress-playground/pull/2460))
-- Removing blog references on Docusaurus. ([#2456](https://github.com/WordPress/wordpress-playground/pull/2456))
+- Add check for SQLite driver missing in target folder. ([#2440](https://github.com/WordPress/wordpress-playground/pull/2440))
+- Adding CLI reference to Playground README. ([#2433](https://github.com/WordPress/wordpress-playground/pull/2433))
+- Adding Gujarati Intro documentation. ([#2450](https://github.com/WordPress/wordpress-playground/pull/2450))
+- Bump WordPress old version demo to version 6.2.1. ([#2460](https://github.com/WordPress/wordpress-playground/pull/2460))
+- Removing blog references on Docusaurus. ([#2456](https://github.com/WordPress/wordpress-playground/pull/2456))
### Contributors
@@ -71,25 +71,24 @@ The following contributors merged PRs in this release:
@adamziel @brandonpayton @fellyph @mho22 @nikunj8866 @zaerl
-
-## [v2.0.6] (2025-08-04)
+## [v2.0.6] (2025-08-04)
### Documentation
-- Adding Contribution pages Spanish translation. ([#2431](https://github.com/WordPress/wordpress-playground/pull/2431))
+- Adding Contribution pages Spanish translation. ([#2431](https://github.com/WordPress/wordpress-playground/pull/2431))
### PHP WebAssembly
-- Fix file locking for PROXYFS nodes that wrap NODEFS. ([#2437](https://github.com/WordPress/wordpress-playground/pull/2437))
+- Fix file locking for PROXYFS nodes that wrap NODEFS. ([#2437](https://github.com/WordPress/wordpress-playground/pull/2437))
### Bug Fixes
-- Translations: Fix command typo in docs. ([#2449](https://github.com/WordPress/wordpress-playground/pull/2449))
+- Translations: Fix command typo in docs. ([#2449](https://github.com/WordPress/wordpress-playground/pull/2449))
### Various
-- Add Japanese translations to Blueprint Bundles and API Consistency. ([#2438](https://github.com/WordPress/wordpress-playground/pull/2438))
-- Translations: Clean up version from PR #2336. ([#2448](https://github.com/WordPress/wordpress-playground/pull/2448))
+- Add Japanese translations to Blueprint Bundles and API Consistency. ([#2438](https://github.com/WordPress/wordpress-playground/pull/2438))
+- Translations: Clean up version from PR #2336. ([#2448](https://github.com/WordPress/wordpress-playground/pull/2448))
### Contributors
@@ -97,16 +96,15 @@ The following contributors merged PRs in this release:
@brandonpayton @fellyph @rollybueno @shimotmk @vipul0425
-
-## [v2.0.5] (2025-07-28)
+## [v2.0.5] (2025-07-28)
### Bug Fixes
-- Fix fcntl() F_GETLK fatal due to undefined flock struct address. ([#2432](https://github.com/WordPress/wordpress-playground/pull/2432))
+- Fix fcntl() F_GETLK fatal due to undefined flock struct address. ([#2432](https://github.com/WordPress/wordpress-playground/pull/2432))
### Various
-- Add Japanese translations to contributing index and sidebar. ([#2434](https://github.com/WordPress/wordpress-playground/pull/2434))
+- Add Japanese translations to contributing index and sidebar. ([#2434](https://github.com/WordPress/wordpress-playground/pull/2434))
### Contributors
@@ -114,40 +112,38 @@ The following contributors merged PRs in this release:
@brandonpayton @shimotmk
-
-## [v2.0.4] (2025-07-25)
+## [v2.0.4] (2025-07-25)
### Public API
-
#### Blueprints
-- Distribute @wp-playground/client without any package.json dependencies. ([#2426](https://github.com/WordPress/wordpress-playground/pull/2426))
+- Distribute @wp-playground/client without any package.json dependencies. ([#2426](https://github.com/WordPress/wordpress-playground/pull/2426))
### Tools
-- Fix ESLint 9 linting in VSCode. ([#2417](https://github.com/WordPress/wordpress-playground/pull/2417))
-- [ xdebug ] Add `--experimental-devtools` option in Playground CLI. ([#2411](https://github.com/WordPress/wordpress-playground/pull/2411))
+- Fix ESLint 9 linting in VSCode. ([#2417](https://github.com/WordPress/wordpress-playground/pull/2417))
+- [ xdebug ] Add `--experimental-devtools` option in Playground CLI. ([#2411](https://github.com/WordPress/wordpress-playground/pull/2411))
### PHP WebAssembly
-- [PHP] Dispatch request.error for all non-zero-exit request handler errors. ([#2429](https://github.com/WordPress/wordpress-playground/pull/2429))
+- [PHP] Dispatch request.error for all non-zero-exit request handler errors. ([#2429](https://github.com/WordPress/wordpress-playground/pull/2429))
### Website
-- Query Monitor plugin support. ([#2415](https://github.com/WordPress/wordpress-playground/pull/2415))
+- Query Monitor plugin support. ([#2415](https://github.com/WordPress/wordpress-playground/pull/2415))
### Internal
-- Skip flaky end-to-end tests in Firefox and Webkit. ([#2425](https://github.com/WordPress/wordpress-playground/pull/2425))
+- Skip flaky end-to-end tests in Firefox and Webkit. ([#2425](https://github.com/WordPress/wordpress-playground/pull/2425))
### Bug Fixes
-- [Xdebug Bridge] Correct error related to unresolved promises in bridge. ([#2422](https://github.com/WordPress/wordpress-playground/pull/2422))
+- [Xdebug Bridge] Correct error related to unresolved promises in bridge. ([#2422](https://github.com/WordPress/wordpress-playground/pull/2422))
### Various
-- Documentation add sidebar to blueprints bundles. ([#2397](https://github.com/WordPress/wordpress-playground/pull/2397))
+- Documentation add sidebar to blueprints bundles. ([#2397](https://github.com/WordPress/wordpress-playground/pull/2397))
### Contributors
@@ -155,16 +151,15 @@ The following contributors merged PRs in this release:
@adamziel @brandonpayton @mho22 @shimotmk
-
-## [v2.0.3] (2025-07-24)
+## [v2.0.3] (2025-07-24)
### Tools
-- [ xdebug ] Add `--experimental-devtools` option in php-wasm CLI. ([#2408](https://github.com/WordPress/wordpress-playground/pull/2408))
+- [ xdebug ] Add `--experimental-devtools` option in php-wasm CLI. ([#2408](https://github.com/WordPress/wordpress-playground/pull/2408))
### Bug Fixes
-- Playground CLI Allow /wordpress subdirs to be mounted before WP install. ([#2382](https://github.com/WordPress/wordpress-playground/pull/2382))
+- Playground CLI Allow /wordpress subdirs to be mounted before WP install. ([#2382](https://github.com/WordPress/wordpress-playground/pull/2382))
### Contributors
@@ -172,23 +167,21 @@ The following contributors merged PRs in this release:
@brandonpayton @mho22
-
-## [v2.0.2] (2025-07-23)
+## [v2.0.2] (2025-07-23)
### Tools
-
#### PHP WebAssembly
-- [ xdebug ] Bridge DBGP session with CDP server. ([#2402](https://github.com/WordPress/wordpress-playground/pull/2402))
+- [ xdebug ] Bridge DBGP session with CDP server. ([#2402](https://github.com/WordPress/wordpress-playground/pull/2402))
### Internal
-- [Build] Preserve optionalDependencies in built package.json. ([#2410](https://github.com/WordPress/wordpress-playground/pull/2410))
+- [Build] Preserve optionalDependencies in built package.json. ([#2410](https://github.com/WordPress/wordpress-playground/pull/2410))
-###
+###
-- Comlink] Throw the original error in the error handler. ([#2407](https://github.com/WordPress/wordpress-playground/pull/2407))
+- Comlink] Throw the original error in the error handler. ([#2407](https://github.com/WordPress/wordpress-playground/pull/2407))
### Contributors
@@ -196,7 +189,6 @@ The following contributors merged PRs in this release:
@adamziel
-
## [v2.0.1] (2025-07-23)
### Blueprints
diff --git a/packages/meta/src/node-es-module-loader/loader.mts b/packages/meta/src/node-es-module-loader/loader.mts
index 0ad21b2628..ee6071d668 100644
--- a/packages/meta/src/node-es-module-loader/loader.mts
+++ b/packages/meta/src/node-es-module-loader/loader.mts
@@ -117,7 +117,7 @@ export async function resolve(
}
const specifierUrl = new URL(specifier, 'file://');
- for (const format of ['raw', 'json', 'url']) {
+ for (const format of ['raw', 'json', 'url', 'base64']) {
if (specifierUrl.searchParams.has(format)) {
// This is a custom format import and can be handled by our custom loader.
return {
@@ -189,6 +189,19 @@ export async function load(
};
}
+ if (context.format === 'base64' || urlObj.searchParams.has('base64')) {
+ // Load binary file content and export as base64 string
+ const content = readFileSync(urlObj.pathname);
+ const base64 = content.toString('base64');
+ return {
+ format: 'module',
+ shortCircuit: true,
+ source: `export default Uint8Array.from(atob(${JSON.stringify(
+ base64
+ )}), c => c.charCodeAt(0));`,
+ };
+ }
+
if (context.format === 'json' || urlObj.pathname.endsWith('.json')) {
const source = readFileSync(urlObj.pathname, 'utf8');
return {
diff --git a/packages/nx-extensions/vite.config.ts b/packages/nx-extensions/vite.config.ts
index 9d23935189..676091c728 100644
--- a/packages/nx-extensions/vite.config.ts
+++ b/packages/nx-extensions/vite.config.ts
@@ -1,11 +1,13 @@
///
import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/nx-extensions',
- plugins: [nxViteTsPaths()],
+ plugins: [nxViteTsPaths(), ...viteGlobalExtensions],
test: {
globals: true,
diff --git a/packages/php-wasm/cli/vite.config.ts b/packages/php-wasm/cli/vite.config.ts
index cc8dbd5fd6..98d7fd867c 100644
--- a/packages/php-wasm/cli/vite.config.ts
+++ b/packages/php-wasm/cli/vite.config.ts
@@ -1,12 +1,14 @@
///
import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
assetsInclude: ['**/*.ini'],
cacheDir: '../../../node_modules/.vite/php-cli',
- plugins: [nxViteTsPaths()],
+ plugins: [nxViteTsPaths(), ...viteGlobalExtensions],
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
diff --git a/packages/php-wasm/fs-journal/vite.config.ts b/packages/php-wasm/fs-journal/vite.config.ts
index 16bb19c021..2f687cecd4 100644
--- a/packages/php-wasm/fs-journal/vite.config.ts
+++ b/packages/php-wasm/fs-journal/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-fs-journal',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/logger/vite.config.ts b/packages/php-wasm/logger/vite.config.ts
index 2b431471c1..3be3cefb35 100644
--- a/packages/php-wasm/logger/vite.config.ts
+++ b/packages/php-wasm/logger/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-logger',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/node-polyfills/vite.config.ts b/packages/php-wasm/node-polyfills/vite.config.ts
index 4b6a4238e1..f43d4cfefa 100644
--- a/packages/php-wasm/node-polyfills/vite.config.ts
+++ b/packages/php-wasm/node-polyfills/vite.config.ts
@@ -5,6 +5,8 @@ import dts from 'vite-plugin-dts';
import viteTsConfigPaths from 'vite-tsconfig-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-node-polyfills',
@@ -18,6 +20,8 @@ export default defineConfig({
tsconfigPath: join(__dirname, 'tsconfig.lib.json'),
pathsToAliases: false,
}),
+
+ ...viteGlobalExtensions,
],
// Uncomment this if you are using workers.
diff --git a/packages/php-wasm/node/vite.config.ts b/packages/php-wasm/node/vite.config.ts
index bc6b3cb728..24ff5870c9 100644
--- a/packages/php-wasm/node/vite.config.ts
+++ b/packages/php-wasm/node/vite.config.ts
@@ -9,6 +9,8 @@ import path from 'path';
import type { Plugin } from 'vite';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig(function () {
return {
@@ -52,6 +54,8 @@ export default defineConfig(function () {
return null;
},
} as Plugin,
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/progress/vite.config.ts b/packages/php-wasm/progress/vite.config.ts
index 567b7f58c2..4a1358447f 100644
--- a/packages/php-wasm/progress/vite.config.ts
+++ b/packages/php-wasm/progress/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-progress',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Uncomment this if you are using workers.
diff --git a/packages/php-wasm/scopes/vite.config.ts b/packages/php-wasm/scopes/vite.config.ts
index 954878335a..f3ae78408d 100644
--- a/packages/php-wasm/scopes/vite.config.ts
+++ b/packages/php-wasm/scopes/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-scope',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/stream-compression/vite.config.ts b/packages/php-wasm/stream-compression/vite.config.ts
index 22318daba0..016a3d9806 100644
--- a/packages/php-wasm/stream-compression/vite.config.ts
+++ b/packages/php-wasm/stream-compression/vite.config.ts
@@ -6,6 +6,8 @@ import * as path from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-stream-compression',
@@ -19,6 +21,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Uncomment this if you are using workers.
diff --git a/packages/php-wasm/universal/vite.config.ts b/packages/php-wasm/universal/vite.config.ts
index c5eceec3d9..ee2722cf17 100644
--- a/packages/php-wasm/universal/vite.config.ts
+++ b/packages/php-wasm/universal/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-universal',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/util/vite.config.ts b/packages/php-wasm/util/vite.config.ts
index 14574f85e7..174c33a54b 100644
--- a/packages/php-wasm/util/vite.config.ts
+++ b/packages/php-wasm/util/vite.config.ts
@@ -7,6 +7,8 @@ import { join } from 'path';
import viteTsConfigPaths from 'vite-tsconfig-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-util',
@@ -21,6 +23,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
// Uncomment this if you are using workers.
diff --git a/packages/php-wasm/web-service-worker/vite.config.ts b/packages/php-wasm/web-service-worker/vite.config.ts
index 3b66b2a2ef..6d9d26df2c 100644
--- a/packages/php-wasm/web-service-worker/vite.config.ts
+++ b/packages/php-wasm/web-service-worker/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-web-service-worker',
@@ -22,6 +24,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
build: {
diff --git a/packages/php-wasm/web/vite.config.ts b/packages/php-wasm/web/vite.config.ts
index bbe3151e3e..e716ef5e06 100644
--- a/packages/php-wasm/web/vite.config.ts
+++ b/packages/php-wasm/web/vite.config.ts
@@ -7,6 +7,8 @@ import dts from 'vite-plugin-dts';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig(({ command }) => {
return {
@@ -103,6 +105,8 @@ export default defineConfig(({ command }) => {
}
},
},
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/php-wasm/xdebug-bridge/vite.config.ts b/packages/php-wasm/xdebug-bridge/vite.config.ts
index 921542c587..05466fcb55 100644
--- a/packages/php-wasm/xdebug-bridge/vite.config.ts
+++ b/packages/php-wasm/xdebug-bridge/vite.config.ts
@@ -5,6 +5,8 @@ import dts from 'vite-plugin-dts';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/php-wasm-xdebug-bridge',
@@ -19,6 +21,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
build: {
diff --git a/packages/playground/cli/public/blueprints.phar b/packages/playground/blueprints/blueprints.phar
similarity index 100%
rename from packages/playground/cli/public/blueprints.phar
rename to packages/playground/blueprints/blueprints.phar
diff --git a/packages/playground/blueprints/src/index.ts b/packages/playground/blueprints/src/index.ts
index 1c3538b9a0..9159479274 100644
--- a/packages/playground/blueprints/src/index.ts
+++ b/packages/playground/blueprints/src/index.ts
@@ -40,6 +40,7 @@ export type {
VFSReference,
VFSResource,
} from './lib/resources';
+export { getV2Runner } from './lib/v2/get-v2-runner';
export { resolveRemoteBlueprint } from './lib/resolve-remote-blueprint';
export { wpContentFilesExcludedFromExport } from './lib/utils/wp-content-files-excluded-from-exports';
diff --git a/packages/playground/blueprints/src/lib/v2/get-v2-runner.ts b/packages/playground/blueprints/src/lib/v2/get-v2-runner.ts
new file mode 100644
index 0000000000..f1ae813799
--- /dev/null
+++ b/packages/playground/blueprints/src/lib/v2/get-v2-runner.ts
@@ -0,0 +1,15 @@
+export async function getV2Runner(): Promise {
+ /**
+ * Dynamically read the file on demand.
+ *
+ * In production, this is encoded as base64 which increases the file size by ~30%. This is
+ * not ideal, but there's no other standard solution for shipping static files with isomorphic
+ * npm CJS+ESM packages so this will have to do until a better solution emerges.
+ */
+ const blueprintsPharBytes = // @ts-ignore
+ (await import('../../../blueprints.phar?base64')).default;
+
+ return new File([blueprintsPharBytes], `blueprints.phar`, {
+ type: 'application/zip',
+ });
+}
diff --git a/packages/playground/blueprints/vite.config.ts b/packages/playground/blueprints/vite.config.ts
index 422e4446ff..6800ad9174 100644
--- a/packages/playground/blueprints/vite.config.ts
+++ b/packages/playground/blueprints/vite.config.ts
@@ -1,5 +1,4 @@
///
-import type { Plugin } from 'vite';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
@@ -9,9 +8,11 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
-const path = (filename: string) => new URL(filename, import.meta.url).pathname;
export default defineConfig({
+ assetsInclude: ['**/*.phar'],
cacheDir: '../../../node_modules/.vite/playground-blueprints',
plugins: [
@@ -25,45 +26,19 @@ export default defineConfig({
root: '../../../',
}),
- {
- name: 'use-correct-blueprints-phar-file-url-in-vitest-environment',
- /**
- * When ran inside the `blueprints.phar` package, vitest resolves
- * `blueprints.phar?url` as `/public/blueprints.phar?url`. However, when ran
- * inside other packages, it resolves as `/@fs/full/path/to/blueprints.phar`.
- *
- * This plugin ensures that the `blueprints.phar` file is always consistently
- * resolved as the latter.
- */
- transform(code, id) {
- if (id.match(new RegExp(`/blueprints\\.phar\\?url`))) {
- const fullyQualifiedPath = '/@fs' + path(id.split('?')[0]);
- return `export default ${JSON.stringify(
- fullyQualifiedPath
- )};`;
- }
- return code;
- },
- } as Plugin,
+ ...viteGlobalExtensions,
],
- // Uncomment this if you are using workers.
- // worker: {
- // plugins: [
- // viteTsConfigPaths({
- // root: '../../../',
- // }),
- // ],
- // },
-
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
+ assetsInlineLimit: 0,
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
name: 'playground-blueprints',
fileName: 'index',
+
// Change this to the formats you want to support.
// Don't forgot to update your package.json as well.
formats: ['es', 'cjs'],
diff --git a/packages/playground/cli/src/blueprints-v2/get-v2-runner.ts b/packages/playground/cli/src/blueprints-v2/get-v2-runner.ts
deleted file mode 100644
index a9a3b78cd4..0000000000
--- a/packages/playground/cli/src/blueprints-v2/get-v2-runner.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-export async function getV2Runner(): Promise {
- let data = null;
-
- /**
- * Avoid a static dependency for now.
- *
- * Playground.wordpress.net does not need to know about the new runner yet, and
- * a static import would force it to download the v2 runner even when it's not needed.
- * This breaks the offline mode as the static assets list is not yet updated to accommodate
- * for the new .phar file.
- */
- // @ts-ignore
- const v2_runner_url = (await import('../../public/blueprints.phar?url'))
- .default;
-
- /**
- * Only load the v2 runner via node:fs when running in Node.js.
- */
- if (typeof process !== 'undefined' && process.versions?.node) {
- let path = v2_runner_url;
- if (path.startsWith('/@fs/')) {
- path = path.slice('/@fs'.length);
- }
- if (path.startsWith('file://')) {
- path = path.slice('file://'.length);
- }
-
- const { readFile } = await import('node:fs/promises');
- data = await readFile(path);
- } else {
- const response = await fetch(v2_runner_url);
- data = await response.blob();
- }
- return new File([data], `blueprints.phar`, {
- type: 'application/zip',
- });
-}
diff --git a/packages/playground/cli/src/blueprints-v2/run-blueprint-v2.ts b/packages/playground/cli/src/blueprints-v2/run-blueprint-v2.ts
index ff717fbbd9..f65a145451 100644
--- a/packages/playground/cli/src/blueprints-v2/run-blueprint-v2.ts
+++ b/packages/playground/cli/src/blueprints-v2/run-blueprint-v2.ts
@@ -4,7 +4,7 @@ import {
type UniversalPHP,
} from '@php-wasm/universal';
import { phpVar } from '@php-wasm/util';
-import { getV2Runner } from './get-v2-runner';
+import { getV2Runner } from '@wp-playground/blueprints';
import {
type BlueprintV2Declaration,
type ParsedBlueprintV2Declaration,
diff --git a/packages/playground/cli/tsconfig.lib.json b/packages/playground/cli/tsconfig.lib.json
index 182203c1e1..51f8c402b8 100644
--- a/packages/playground/cli/tsconfig.lib.json
+++ b/packages/playground/cli/tsconfig.lib.json
@@ -5,6 +5,10 @@
"declaration": true,
"types": ["node"]
},
- "include": ["src/**/*.ts", "tests/mounts.spec.ts"],
+ "include": [
+ "src/**/*.ts",
+ "tests/mounts.spec.ts",
+ "../blueprints/src/lib/v2/get-v2-runner.ts"
+ ],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
diff --git a/packages/playground/cli/vite.config.ts b/packages/playground/cli/vite.config.ts
index f76ab1f9cf..a9b1f359be 100644
--- a/packages/playground/cli/vite.config.ts
+++ b/packages/playground/cli/vite.config.ts
@@ -7,6 +7,8 @@ import dts from 'vite-plugin-dts';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
/**
* @TODO: Consider rsbuild for this:
@@ -86,6 +88,7 @@ const plugins = [
}
},
},
+ ...viteGlobalExtensions,
] as PluginOption[];
const external = [
diff --git a/packages/playground/client/vite.config.ts b/packages/playground/client/vite.config.ts
index 3fb1394c81..09399ddc14 100644
--- a/packages/playground/client/vite.config.ts
+++ b/packages/playground/client/vite.config.ts
@@ -10,6 +10,8 @@ import ignoreDataImports from '../ignore-data-imports';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { buildVersionPlugin } from '../../vite-extensions/vite-build-version';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
function validateOrigin(origin: string) {
try {
@@ -42,7 +44,7 @@ export default defineConfig({
}),
ignoreWasmImports(),
ignoreDataImports(),
-
+ ...viteGlobalExtensions,
// @wp-playground/client doesn't actually use the remote-config virtual
// module, @wp-playground/remote package does. @wp-playground/client imports
// a few things from @wp-playground/remote and, even though it doesn't
diff --git a/packages/playground/common/vite.config.ts b/packages/playground/common/vite.config.ts
index 9b0c7fce88..91305267d9 100644
--- a/packages/playground/common/vite.config.ts
+++ b/packages/playground/common/vite.config.ts
@@ -5,6 +5,8 @@ import dts from 'vite-plugin-dts';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
const path = (filename: string) => new URL(filename, import.meta.url).pathname;
export default defineConfig({
assetsInclude: ['**/*.wasm', '**/*.dat', '*.zip'],
@@ -18,6 +20,8 @@ export default defineConfig({
tsconfigPath: path('tsconfig.lib.json'),
pathsToAliases: false,
}),
+
+ ...viteGlobalExtensions,
],
build: {
diff --git a/packages/playground/components/vite.config.ts b/packages/playground/components/vite.config.ts
index 0fcf906a4b..44a564ebe4 100644
--- a/packages/playground/components/vite.config.ts
+++ b/packages/playground/components/vite.config.ts
@@ -8,6 +8,8 @@ import { join } from 'path';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
cacheDir: '../../../node_modules/.vite/playground-components',
@@ -21,6 +23,8 @@ export default defineConfig({
viteTsConfigPaths({
root: '../../../',
}),
+
+ ...viteGlobalExtensions,
],
css: {
diff --git a/packages/playground/remote/vite.config.ts b/packages/playground/remote/vite.config.ts
index 09ca73d3a6..4b11239c0d 100644
--- a/packages/playground/remote/vite.config.ts
+++ b/packages/playground/remote/vite.config.ts
@@ -12,6 +12,8 @@ import { copyFileSync, existsSync } from 'fs';
import { buildVersionPlugin } from '../../vite-extensions/vite-build-version';
// eslint-disable-next-line @nx/enforce-module-boundaries
import virtualModule from '../../vite-extensions/vite-virtual-module';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
const path = (filename: string) => new URL(filename, import.meta.url).pathname;
@@ -38,6 +40,7 @@ const plugins = [
}
},
} as Plugin,
+ ...viteGlobalExtensions,
buildVersionPlugin('remote-config'),
];
@@ -58,7 +61,7 @@ export default defineConfig(({ mode }) => {
);
return {
- assetsInclude: ['**/*.wasm', '**/*.dat', '*.zip'],
+ assetsInclude: ['**/*.wasm', '**/*.dat', '**/*.phar', '*.zip'],
cacheDir: '../../../node_modules/.vite/playground',
// Bundled WordPress files live in a separate dependency-free `wordpress`
// package so that every package may use them without causing circular
diff --git a/packages/playground/storage/vite.config.ts b/packages/playground/storage/vite.config.ts
index 91855c1577..b50350bd6e 100644
--- a/packages/playground/storage/vite.config.ts
+++ b/packages/playground/storage/vite.config.ts
@@ -6,6 +6,8 @@ import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
import ignoreWasmImports from '../ignore-wasm-imports';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default defineConfig({
base: '/',
@@ -23,6 +25,8 @@ export default defineConfig({
root: '../../../',
}),
ignoreWasmImports(),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/playground/sync/vite.config.ts b/packages/playground/sync/vite.config.ts
index 256788aa39..18578f0ad6 100644
--- a/packages/playground/sync/vite.config.ts
+++ b/packages/playground/sync/vite.config.ts
@@ -7,6 +7,8 @@ import ignoreWasmImports from '../ignore-wasm-imports';
import ignoreDataImports from '../ignore-data-imports';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
export default {
base: '/',
@@ -25,6 +27,8 @@ export default {
}),
ignoreWasmImports(),
ignoreDataImports(),
+
+ ...viteGlobalExtensions,
],
// Configuration for building your library.
diff --git a/packages/playground/website/playwright/e2e/deployment.spec.ts b/packages/playground/website/playwright/e2e/deployment.spec.ts
index 84f49254b6..174b27f925 100644
--- a/packages/playground/website/playwright/e2e/deployment.spec.ts
+++ b/packages/playground/website/playwright/e2e/deployment.spec.ts
@@ -145,6 +145,8 @@ test('offline mode – the app should load even when the server goes offline', a
server!.switchToNewVersion();
+ // First page load – the service worker gets installed, the page becomes controlled. Some
+ // assets are fetched before the service worker takes over and caches them.
await page.goto(`${url}`);
await website.waitForNestedIframes();
@@ -153,7 +155,14 @@ test('offline mode – the app should load even when the server goes offline', a
'My WordPress Website'
);
+ // Second page load – handled by the service worker – the fetched assets are getting cached.
+ await page.reload();
+ await website.waitForNestedIframes();
+
+ // Kill the server.
server!.kill();
+
+ // From now on, the critical application assets should be cached.
await page.reload();
await website.waitForNestedIframes();
diff --git a/packages/playground/website/vite.config.ts b/packages/playground/website/vite.config.ts
index 847fba87eb..30abb6a0b9 100644
--- a/packages/playground/website/vite.config.ts
+++ b/packages/playground/website/vite.config.ts
@@ -26,6 +26,8 @@ import { buildVersionPlugin } from '../../vite-extensions/vite-build-version';
import { listAssetsRequiredForOfflineMode } from '../../vite-extensions/vite-list-assets-required-for-offline-mode';
// eslint-disable-next-line @nx/enforce-module-boundaries
import virtualModule from '../../vite-extensions/vite-virtual-module';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
const proxy: CommonServerOptions['proxy'] = {
'^/plugin-proxy': {
@@ -68,7 +70,7 @@ export default defineConfig(({ command, mode }) => {
server: {
port: websiteDevServerPort,
host: websiteDevServerHost,
- allowedHosts: ['playground.test'],
+ allowedHosts: ['playground.test', 'playground-preview.test'],
proxy: {
...proxy,
// Proxy requests to the remote content through this server for dev
@@ -90,6 +92,7 @@ export default defineConfig(({ command, mode }) => {
}),
ignoreWasmImports(),
ignoreDataImports(),
+ ...viteGlobalExtensions,
buildVersionPlugin('website-config'),
virtualModule({
name: 'cors-proxy-url',
diff --git a/packages/playground/wordpress-builds/vite.config.ts b/packages/playground/wordpress-builds/vite.config.ts
index 8200f9e401..1496d6a832 100644
--- a/packages/playground/wordpress-builds/vite.config.ts
+++ b/packages/playground/wordpress-builds/vite.config.ts
@@ -6,6 +6,8 @@ import dts from 'vite-plugin-dts';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
const path = (filename: string) => new URL(filename, import.meta.url).pathname;
export default defineConfig({
@@ -40,6 +42,8 @@ export default defineConfig({
return code;
},
} as Plugin,
+
+ ...viteGlobalExtensions,
],
build: {
diff --git a/packages/playground/wordpress/vite.config.ts b/packages/playground/wordpress/vite.config.ts
index a81340e834..23e5404c99 100644
--- a/packages/playground/wordpress/vite.config.ts
+++ b/packages/playground/wordpress/vite.config.ts
@@ -6,6 +6,8 @@ import dts from 'vite-plugin-dts';
import { viteTsConfigPaths } from '../../vite-extensions/vite-ts-config-paths';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { getExternalModules } from '../../vite-extensions/vite-external-modules';
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import viteGlobalExtensions from '../../vite-extensions/vite-global-extensions';
const path = (filename: string) => new URL(filename, import.meta.url).pathname;
export default defineConfig({
@@ -40,6 +42,8 @@ export default defineConfig({
return code;
},
} as Plugin,
+
+ ...viteGlobalExtensions,
],
build: {
diff --git a/packages/vite-extensions/vite-global-extensions.ts b/packages/vite-extensions/vite-global-extensions.ts
new file mode 100644
index 0000000000..75a0a0cf8d
--- /dev/null
+++ b/packages/vite-extensions/vite-global-extensions.ts
@@ -0,0 +1,19 @@
+import fs from 'node:fs';
+
+const vitePlugins = [
+ {
+ name: 'base64-loader',
+ transform(_: any, id: string) {
+ const url = new URL(id, 'file://');
+ if (!url.searchParams.has('base64')) return null;
+ const path = url.pathname;
+
+ const data = fs.readFileSync(path);
+ const base64 = data.toString('base64');
+
+ return `export default Uint8Array.from(atob('${base64}'), c => c.charCodeAt(0));`;
+ },
+ },
+];
+
+export default vitePlugins;
diff --git a/packages/vite-extensions/vite-list-assets-required-for-offline-mode.ts b/packages/vite-extensions/vite-list-assets-required-for-offline-mode.ts
index c62ef96636..5e9d1161bd 100644
--- a/packages/vite-extensions/vite-list-assets-required-for-offline-mode.ts
+++ b/packages/vite-extensions/vite-list-assets-required-for-offline-mode.ts
@@ -16,6 +16,7 @@ const patternsToNotCache = [
/\/lib\/.*/, // Remote lib files
/\/test-fixtures\/.*/, // Test fixtures
'/index.js',
+
/**
* Source maps are not required to run the site and can be quite large.
*/
@@ -61,6 +62,7 @@ const patternsToNotCache = [
/^\/assets\/php_.*\.js$/, // PHP JS files
/^\/assets\/wp-.*\.zip$/, // Minified WordPress builds and static assets bundles
/^\/assets\/sqlite-database-integration-[\w]+\.zip/, // SQLite plugin
+ /^\/assets\/blueprints-.*\.phar$/, // Blueprints v2 runner
];
function listFiles(dirPath: string, fileList: string[] = []) {