Skip to main content
Version: Next

Dynamic Module Loading

The extension architecture leverages Webpack's Module Federation to enable dynamic loading of frontend assets at runtime. This sophisticated mechanism involves several key concepts:

Module Federation allows extensions to be built and deployed independently while sharing dependencies with the host application. Extensions expose their entry points through the federation configuration:

new ModuleFederationPlugin({
name: 'my_extension',
filename: 'remoteEntry.[contenthash].js',
exposes: {
'./index': './src/index.tsx',
},
externalsType: 'window',
externals: {
'@apache-superset/core': 'superset',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
'antd-v5': { singleton: true }
}
})

externals and externalsType ensure that extensions use the host's implementation of shared packages rather than bundling their own copies.

shared dependencies prevent duplication of common libraries like React and Ant Design avoiding version conflicts and reducing bundle size.

This configuration tells Webpack that when the extension imports from @apache-superset/core, it should resolve to window.superset at runtime, where the host application provides the actual implementation. The following diagram illustrates how this works in practice:

Image

During extension registration, the host application fetches the remote entry file and dynamically loads the extension's modules without requiring a rebuild or restart of Superset.

On the host application side, the @apache-superset/core package will be mapped to the corresponding implementations during bootstrap in the setupExtensionsAPI function.

import * as supersetCore from '@apache-superset/core';
import {
authentication,
core,
commands,
environment,
extensions,
sqlLab,
} from 'src/extensions';

export default function setupExtensionsAPI() {
window.superset = {
...supersetCore,
authentication,
core,
commands,
environment,
extensions,
sqlLab,
};
}