Skip to content

fix(plugin): rebuild admin extensions in develop mode - #15506

Closed
Chris79OG wants to merge 3 commits into
medusajs:developfrom
Chris79OG:luminaflow/plugin-admin-develop-watch
Closed

fix(plugin): rebuild admin extensions in develop mode#15506
Chris79OG wants to merge 3 commits into
medusajs:developfrom
Chris79OG:luminaflow/plugin-admin-develop-watch

Conversation

@Chris79OG

@Chris79OG Chris79OG commented May 26, 2026

Copy link
Copy Markdown

Summary

What — What changes are introduced in this PR?

This adds plugin admin extension handling to medusa plugin:develop: admin extensions are built on startup when src/admin exists, watched during development, and rebuilt when files are added, changed, or removed.

Why — Why are these changes relevant or necessary?

plugin:develop currently republishes backend plugin changes, but admin route changes are not rebuilt or republished while the command is running. This leaves plugin authors restarting the develop command to see admin extension changes, which is the issue reported in #15505.

How — How have these changes been implemented?

The develop command now initializes the admin bundler, builds plugin admin extensions once before entering watch mode, and starts a src/admin watcher through the framework compiler. The watcher coalesces rapid changes while a build is already running, rebuilds admin extensions through the existing bundler path, and only triggers the existing publish callback after a successful admin build. It also logs when the admin extension watcher is ready, matching the backend watcher experience.

Testing — How have these changes been tested, or how can the reviewer test the feature?

Local verification:

  • git diff --check

Reviewer repro path:

  1. Use a plugin project with a src/admin extension.
  2. Run medusa plugin:develop.
  3. Confirm admin extensions are built during startup.
  4. Edit, add, or remove a file under src/admin.
  5. Confirm the command logs an admin extension rebuild and republishes the plugin after the build succeeds.

Examples

A plugin with src/admin/routes/custom/page.tsx can keep medusa plugin:develop running while editing that route. The plugin admin extension build is rerun after the file change and the updated plugin package is republished through the same yalc callback used for backend changes.


Checklist

Please ensure the following before requesting a review:

  • I have added a changeset for this PR
  • The changes are covered by relevant tests
  • I have verified the code works as intended locally
  • I have linked the related issue(s) if applicable

Additional Context

Fixes #15505.

I did not add a dedicated chokidar integration test because this path depends on the plugin develop watcher lifecycle and admin bundler side effects. The implementation reuses the existing buildPluginAdminExtensions path and the existing publish callback, with a small queue around rebuilds to avoid overlapping admin builds during rapid file changes.

Why:
- plugin:develop ignored src/admin changes, so custom admin routes only refreshed after plugin:publish
- watching admin extensions and rebuilding them feeds the existing yalc publish callback

Verified:
- git diff --check
@Chris79OG
Chris79OG requested a review from a team as a code owner May 26, 2026 14:13
@changeset-bot

changeset-bot Bot commented May 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: acaebe3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 78 packages
Name Type
@medusajs/medusa Patch
@medusajs/framework Patch
@medusajs/test-utils Patch
@medusajs/medusa-oas-cli Patch
integration-tests-http Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/caching Patch
@medusajs/cart Patch
@medusajs/currency Patch
@medusajs/customer Patch
@medusajs/event-bus-local Patch
@medusajs/event-bus-redis Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/order Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/product Patch
@medusajs/promotion Patch
@medusajs/rbac Patch
@medusajs/region Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/store Patch
@medusajs/tax Patch
@medusajs/translation Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/file-s3 Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/draft-order Patch
@medusajs/loyalty-plugin Patch
@medusajs/core-flows Patch
@medusajs/oas-github-ci Patch
@medusajs/js-sdk Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/types Patch
@medusajs/utils Patch
@medusajs/workflows-sdk Patch
@medusajs/http-types-generator Patch
@medusajs/cli Patch
@medusajs/deps Patch
@medusajs/telemetry Patch
@medusajs/admin-bundler Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/dashboard Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@medusa-os-bot

medusa-os-bot Bot commented May 26, 2026

Copy link
Copy Markdown

Thank you for your contribution, @Chris79OG!

Nice scoping on this — the fix is focused and the linked issue (#15505) is verified and tagged help-wanted. Implementation looks sound; the isBuilding / hasQueuedBuild coalescing is a clean way to handle rapid file changes during a rebuild.

A few things to address before we can move forward:

Required changes:

  • Add a changeset (yarn changeset) — the changeset-bot has already flagged this. Use the patch bump type for @medusajs/medusa and @medusajs/framework, with a message following the fix(medusa, framework): ... format.
  • Update the PR description to follow our pull request template. The template requires explicit What, Why, How, and Testing sections — the current "What changed" + "Verification" structure is close, but the Why and How are not spelled out, and the Testing section needs concrete repro/verification steps (running git diff --check is not test coverage).

Notes (non-blocking):

  • It would be worth adding a ready log similar to developPluginBackend ("watching for file changes") so the dev experience is consistent across both watchers.
  • Tests for chokidar-driven flows are tricky, but if you have a way to exercise the watcher in packages/core/framework, it would help guard against future regressions. Acceptable to omit if non-trivial.

Triggered by: new PR opened

@medusa-os-bot

medusa-os-bot Bot commented May 26, 2026

Copy link
Copy Markdown

Thanks for addressing the earlier feedback, @Chris79OG! 🎉

After a second look, this PR is in good shape:

✅ PR template now complete (What/Why/How/Testing)
✅ Changeset added with the expected `fix(medusa, framework): ...` format
✅ Linked to a verified `help-wanted` issue (#15505)
✅ Follows Medusa's conventions
✅ `ready` log added on the admin watcher, matching `developPluginBackend`
✅ `#hasPluginAdminExtensions()` cleanly skips the build when `src/admin` is absent

A team member will do the final review before this is merged.

Notes (non-blocking):

  • The coalescing loop in `developPluginAdminExtensions` reuses the original `file` / `action` on follow-up iterations, so the `Rebuilding admin extensions` log and the `onFileChange` callback will report the first triggering file even when the rebuild actually picks up subsequently-changed files. The `publishChanges` callback doesn't care about the file path, so this is cosmetic — just something to be aware of when reading the logs.
  • `chokidar.watch(["src/admin"], …)` is set up regardless of whether `src/admin` exists. That mirrors `developPluginBackend`, so it's consistent — but worth noting that creating `src/admin` after `plugin:develop` is running may not be picked up depending on chokidar behaviour on the platform.

Triggered by: new commit pushed

@medusa-os-bot

medusa-os-bot Bot commented May 26, 2026

Copy link
Copy Markdown

Thanks for the quick turnaround, @Chris79OG! 🎉

Both prior required changes have been addressed:

✅ Changeset added with the correct fix(medusa, framework): ... format and patch bump
✅ PR description now follows the template (explicit What, Why, How, Testing sections)
ready log added for the admin watcher (the non-blocking note from last review)

After this round of review, this PR looks good to us:

✅ Linked to a verified issue (#15505, tagged help-wanted)
✅ Follows contribution guidelines
✅ Follows Medusa's conventions
✅ No security or performance concerns

Notes (non-blocking):

  • In developPluginAdminExtensions, when a rebuild is queued while another is in progress, the next iteration of the loop reuses the original file / action captured in the closure:
    do {
      hasQueuedBuild = false
      isBuilding = true
      this.#logger.info(`${file} updated: Rebuilding admin extensions`)
      ...
      if (buildSucceeded) {
        onFileChange?.(file, action)
      }
    } while (hasQueuedBuild)
    The log line and onFileChange callback report the originally-triggering file rather than the latest change. Functionally fine since the publish callback ignores those args and the rebuild is full, but if you want the log to reflect reality you could track the latest file/action in module-scoped vars updated on each watcher event.

A team member will do the final review before merging. Thanks again!

Triggered by: PR description updated

@medusa-os-bot

medusa-os-bot Bot commented May 26, 2026

Copy link
Copy Markdown

Thanks for the follow-up, @Chris79OG! 🎉

The new commit cleanly addresses the prior non-blocking note — latestQueuedFile/latestQueuedAction are now captured in the watcher events and propagated into the next iteration via currentFile/currentAction, so the rebuild log and onFileChange callback reflect the most recent queued change rather than the first triggering file.

Nothing else has surfaced since the last review:

✅ PR template complete (What/Why/How/Testing)
✅ Changeset present with correct fix(medusa, framework): ... format
✅ Linked to verified help-wanted issue (#15505)
#hasPluginAdminExtensions() short-circuits cleanly when src/admin is absent
✅ Watcher ready log matches developPluginBackend
✅ Coalescing logic correctly tracks latest queued change
✅ No security or performance concerns
✅ Follows Medusa's conventions

initial-approval remains; a team member will do the final review before merging.

Triggered by: new commit pushed

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@NicolasGorga

Copy link
Copy Markdown
Contributor

@Chris79OG I haven't been able to reproduce the issue so won't be picking this up until I have clear reproduction steps. Did you experience this issue yourself?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Custom admin route in plugin is not automatically reloaded/rebuilt in plugin:develop mode

2 participants