Skip to content

Serve client on 127.0.0.1:5400/client/index.js when running npm run dev#3302

Open
ashfame wants to merge 4 commits intotrunkfrom
devex_improvement_using_dynamic_client
Open

Serve client on 127.0.0.1:5400/client/index.js when running npm run dev#3302
ashfame wants to merge 4 commits intotrunkfrom
devex_improvement_using_dynamic_client

Conversation

@ashfame
Copy link
Member

@ashfame ashfame commented Feb 24, 2026

This pull request enhances the local development experience for the Playground website by adding a Vite plugin that serves the built @wp-playground/client library at /client/, closely matching the production environment. The plugin also auto-builds the client library if it's missing and warns if the build is stale, ensuring developers always have an up-to-date client bundle available during development.

Key changes:

Development server enhancements:

  • Added a custom Vite plugin (serve-client-library) in vite.config.ts to serve the @wp-playground/client library at /client/, auto-build it if missing, and trigger a rebuild if source files are newer than the built output. This improves local development parity with production and reduces manual build steps.

Utility improvements:

  • Extended the Node.js fs imports in vite.config.ts to include readFileSync, readdirSync, and statSync, supporting the new plugin's file system operations.

Motivation for the change, related issues

In external projects, when we need to modify playground code and run that to fix an issue, we were not able to fetch the client dynamically from local env, as we were doing it in production environment.

Related to https://linear.app/a8c/issue/ARC-1443/launch-on-wordpresscom-takes-30-seconds-without-any-loading-spinner

Testing Instructions (or ideally a Blueprint)

  • Checkout this branch locally
  • Run npm run dev
  • From an external project, just swap the playground.wordpress.net host with 127.0.0.1 for /remote.html and /client/index.js urls.
  • Modify playground code and use it right away in external project using Playground.

@ashfame ashfame self-assigned this Feb 24, 2026
@ashfame ashfame marked this pull request as ready for review February 24, 2026 20:07
Copilot AI review requested due to automatic review settings February 24, 2026 20:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Vite dev-server middleware to serve the built @wp-playground/client bundle at /client/ (mirroring production) and automatically triggers an Nx build when the bundle is missing or stale.

Changes:

  • Added serve-client-library Vite plugin to serve /client/* from dist/packages/playground/client.
  • Implemented auto-build and staleness detection (source mtime vs built index.js mtime).
  • Expanded node:fs imports to support reading and stat’ing served files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Replace runtime require('child_process') with a static import from
node:child_process, log stderr on build failures, and sanitize the
request URL to prevent path traversal and query-string issues.
@ashfame ashfame requested a review from Copilot February 24, 2026 20:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let buildInProgress = false;
let stalenessWarned = false;

function newestMtimeIn(dir: string): number {
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name newestMtimeIn uses abbreviation 'mtime' which may not be immediately clear to all developers. Consider renaming to getNewestModificationTimeIn or getLatestFileModificationTime for better clarity.

Copilot uses AI. Check for mistakes.
Comment on lines +238 to +239
const urlPath = new URL(req.url, 'http://localhost')
.pathname;
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The req.url is used directly in URL construction without validation. Malformed URLs could cause the URL constructor to throw an exception. Consider wrapping this in a try-catch block to handle potential URL parsing errors gracefully.

Suggested change
const urlPath = new URL(req.url, 'http://localhost')
.pathname;
let urlPath: string;
try {
urlPath = new URL(req.url, 'http://localhost')
.pathname;
} catch {
res.statusCode = 400;
res.end('Invalid request URL');
return;
}

Copilot uses AI. Check for mistakes.
@ashfame
Copy link
Member Author

ashfame commented Feb 24, 2026

@copilot Can you mark your comments that has been addressed as resolved?

Copy link
Contributor

Copilot AI commented Feb 24, 2026

@ashfame I've opened a new pull request, #3303, to work on those changes. Once the pull request is ready, I'll request review from you.

@bgrgicak
Copy link
Collaborator

@ashfame we have a npm run local-package-repository feature. Would that solve your issue?
It currently only supports serving all packages which is slow to rebuild, but I could see it being useful to pass an argument to server only one package and its dependencies.

@ashfame
Copy link
Member Author

ashfame commented Feb 25, 2026

@bgrgicak It might, but won't be as convenient as just running a single command and having it work exactly as we have in production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants