michael-s-molina opened a new pull request, #38346:
URL: https://github.com/apache/superset/pull/38346
### SUMMARY
This is **Part 1** of a planned refactor of the Superset extensions frontend
contribution system. It replaces the JSON-based contribution declarations in
`extension.json` with a code-first approach where extensions register their
contributions directly in their entry point (`index.tsx`) as module-level side
effects.
> **Note:** Backend changes (e.g. contribution point validation, permission
enforcement) will be tackled in a separate follow-up PR. Generating static
contribution manifests at build time (for tooling, documentation, and IDE
support) will also be addressed in a follow-up.
#### What changed
**Code-first contributions**
Instead of declaring contributions in `extension.json`:
```json
// Before — extension.json
{
"frontend": {
"contributions": {
"menus": {
"sqllab": {
"editor": {
"primary": [{ "view": "sqllab.editor", "command": "my_ext.open"
}]
}
}
}
}
}
}
```
Extensions now register directly in code:
```typescript
// After — index.tsx (module-level side effect)
menus.registerMenuItem(
{ view: 'sqllab.editor', command: 'my_ext.open' },
'sqllab.editor',
'primary',
);
```
The same pattern applies to views, commands, and editors — all registered
via the `@apache-superset/core` API at module load time.
**New `@apache-superset/core` API modules**
- `views` — `registerView(view, location, provider)` / `getViews(location)`
- `menus` — `registerMenuItem(item, location, group)` / `getMenu(location)`
Both are now exposed on `window.superset` alongside existing `commands` and
`editors` APIs.
**`ExtensionsLoader` (replaces `ExtensionsManager`)**
A new, focused loader that handles webpack Module Federation initialization.
After loading each extension's remote entry, it calls
`container.get('./index')` and executes the factory. This triggers all
module-level side-effect registrations (views, menus, commands, editors)
synchronously before the loader resolves.
**Extension initialization gating**
`ExtensionsStartup` was changed from a fire-and-forget side-effect component
into a gating wrapper:
- Properly `await`s `initializeExtensions()` before rendering application
routes
- Returns `null` until extensions are fully loaded, then renders `children`
- The nav menu and toast container are intentionally left outside the gate
This ensures all registries are populated before any component reads from
them, making `menus.getMenu()`, `views.getViews()`, and `commands.getCommand()`
reliable as plain synchronous reads with no reactivity mechanism needed.
### TESTING INSTRUCTIONS
1. Enable the `ENABLE_EXTENSIONS` feature flag
2. Configure `LOCAL_EXTENSIONS` or `EXTENSIONS_PATH` in your Superset config
3. Load an extension that registers views (e.g. a panel), primary menu items
(icon buttons), and secondary menu items (dropdown entries)
4. Navigate to SQL Lab — verify:
- Extension panels appear as tabs in the South Pane
- Primary menu items (icon buttons) appear in the SQL editor top bar
- Secondary menu items appear in the `...` dropdown in the SQL editor top
bar
5. Verify no console errors about undefined registries or missing module
federation containers
### ADDITIONAL INFORMATION
<!--- Check any relevant boxes with "x" -->
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]