feat(lightspeed): restructure plugin to make NFS the default entry point with OFS at legacy subpath#3513
Conversation
… for FAB and translations - Add lightspeedFABModuleExport.ts and lightspeedTranslationsModuleExport.ts as dedicated default-export entry points required by dynamicFrontendFeaturesLoader - Update package.json exports, typesVersions, and scalprum.exposedModules to register both modules as separate Module Federation containers - Fix React Context duplication across MF boundaries using globalThis singleton pattern in LightspeedDrawerContext, resolving "useLightspeedDrawerContext must be used within a LightspeedDrawerProvider" error in Dock-to-Window mode Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3513 +/- ##
=======================================
Coverage 53.62% 53.62%
=======================================
Files 2256 2255 -1
Lines 85870 85880 +10
Branches 24186 24184 -2
=======================================
+ Hits 46046 46053 +7
- Misses 38333 38336 +3
Partials 1491 1491
*This pull request uses carry forward flags. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
…path export Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
|
|
<img width="1512" height="982" alt="S_ 2026-06-22 at 10 36 35 AM" src="https://github.com/user-attachments/assets/3014e58e-1f4d-41a2-9799-a35681d0d209" / Some styles issue is there, need some cleaning. Fixing that. |



Description
Restructures the Lightspeed plugin source layout to make the New Frontend System (NFS) the primary/default entry point, while preserving full backward compatibility for the old frontend system via a dedicated
./legacysubpath export.Previously, the NFS code lived under
src/alpha/and was accessed via@red-hat-developer-hub/backstage-plugin-lightspeed/alpha, while the legacy code was the default export at the package root. This PR inverts that relationship — NFS is now the default (import from '@red-hat-developer-hub/backstage-plugin-lightspeed'), and legacy components are accessed via@red-hat-developer-hub/backstage-plugin-lightspeed/legacy.All public API symbols have been promoted from
@alphato@public, signaling production readiness for the NFS mode.Also
This PR adds dedicated Module Federation entry points for the Lightspeed FAB (Floating Action Button) module and the Translations module, and fixes a React Context duplication bug that occurs across MF chunk boundaries in the New Frontend System (NFS).
These changes are required because
dynamicFrontendFeaturesLoader()in Backstage NFS only loads default exports from each exposed module. The existinglightspeedFABModuleandlightspeedTranslationsModuleare named exports from./src/alpha/index.tsx, which means they cannot be discovered and loaded by the NFS dynamic plugin loader without a dedicated entry point that re-exports them asdefault.Key Changes
src/alpha/index.tsx→src/index.tsxsrc/index.ts→src/legacyExports.ts+ new./legacysubpathLegacyscalprum exposed modulemodule: Legacy) in the old frontend systemapp-config.dynamic.yamladdsmodule: Legacy@alpha→@publicon all exportssrc/lightspeedFABModuleExport.ts+src/lightspeedTranslationsModuleExport.ts(new)lightspeedFABModuleandlightspeedTranslationsModuleare named exports, invisible todynamicFrontendFeaturesLoader(). These files re-export them asdefault.src/components/LightspeedDrawerContext.tsx— globalThis singletoncreateContext()to produce duplicates. "Dock to Window" mode failed because provider and consumer held different Context objects. TheglobalThissingleton ensures one shared instance.Migration Guide
For NFS consumers (new):
For legacy consumers:
Test it on RHDH-Local Steps
Prerequisites
Build the Lightspeed dynamic plugin
NFS mode
1. Enable NFS mode in RHDH-local
Ensure the following environment variables are set in /path/to/rhdh-local/.env:
2. Configure dynamic plugins
In your dynamic-plugins.override.yaml (or equivalent), ensure the local lightspeed frontend is enabled:
3. Configure NFS extensions
Create or update configs/app-config/app-config.local.yaml:
Important: The order of app-root-wrapper extensions matters.
app/drawer must come before app/lightspeed-fab to ensure correct React Context nesting.
4. Volume Mount for Lightspeed Configs
The
developer-lightspeed/compose.yamlfile must exist with the following content to mount Lightspeed configuration files into the containers:This is required for both NFS and OFS (Old Frontend System) because the dynamic plugin installer needs access to
developer-lightspeed/configs/dynamic-plugins/dynamic-plugins.lightspeed.yaml— which is referenced as anincludespath indynamic-plugins.override.yaml.Without this volume mount, the installer either fails to resolve the include path or silently skips the Lightspeed plugin configuration entirely.
When starting RHDH-local, always include this compose file:
4. Start RHDH-local
5. Verify module federation endpoints
Once RHDH is running, confirm the new modules are exposed:
Expected: entries for LightspeedFABModule and LightspeedTranslationsModule
6. Cleanup
Steps to run in OFS mode
1. Configure dynamic plugins for OFS
In
developer-lightspeed/configs/dynamic-plugins/dynamic-plugins.lightspeed.yaml, the Lightspeed plugin entry must includepluginConfig.dynamicPlugins.frontendwith explicitmodule: Legacyon all mount points and routes:2. Ensure volume mount exists
The
developer-lightspeed/compose.yamlfile must exist (see "Volume Mount for Lightspeed Configs" section above).2. Start RHDH-local
UI after changes
OFS
S_.2026-06-21.at.5.54.46.PM.mov
NFS
S_.2026-06-21.at.6.06.48.PM.mov
Fixed
✔️ Checklist