Framework application functionality for managing and routing to multiple sub-applications with configurable layouts and error handling.
Configuration interface for framework applications that manage sub-applications.
/**
* Configuration for framework applications managing sub-applications
*/
interface FrameworkConfig {
/** Function to fetch sub-application configurations */
getApps?: (data?: any) => (AppConfig[] | Promise<AppConfig[]>);
/** App router configuration (excluding lifecycle callbacks) */
appRouter?: Omit<AppRouterProps, 'onRouteChange' | 'onAppEnter' | 'onAppLeave'>;
/** Custom layout component for the framework */
layout?: ComponentType<any>;
/** Custom AppRoute component */
AppRoute?: typeof AppRoute;
}
// Supporting types
interface AppRouterProps {
onRouteChange?: (pathname: string, query: object, hash: string, routeType: string) => void;
onAppEnter?: (appConfig: AppConfig) => void;
onAppLeave?: (appConfig: AppConfig) => void;
ErrorComponent?: ComponentType<{ error: Error }>;
LoadingComponent?: ComponentType<any>;
NotFoundComponent?: ComponentType<any>;
shouldAssetsRemove?: (asset: string, app: AppConfig) => boolean;
}
type ComponentType<P = {}> = React.ComponentType<P>;
type AppRoute = typeof import('@ice/stark').AppRoute;Helper function to define framework configuration with optional function wrapper.
/**
* Helper function to define framework configuration
* @param config - Framework configuration object or function returning config
* @returns Resolved framework configuration
*/
function defineFrameworkConfig(config: FrameworkConfig | (() => FrameworkConfig)): FrameworkConfig;Usage Examples:
import { defineFrameworkConfig } from '@ice/plugin-icestark/types';
// Static configuration
export const icestark = defineFrameworkConfig({
getApps: () => [
{
name: 'dashboard',
activePath: '/dashboard',
container: '#dashboard-container',
url: ['//localhost:3001/build/js/index.js'],
},
{
name: 'settings',
activePath: '/settings',
container: '#settings-container',
url: ['//localhost:3002/build/js/index.js'],
},
],
});
// Dynamic configuration with async app loading
export const icestark = defineFrameworkConfig(() => ({
getApps: async (appData) => {
const response = await fetch('/api/micro-apps');
return response.json();
},
appRouter: {
ErrorComponent: ({ error }) => <div>Error: {error.message}</div>,
LoadingComponent: () => <div>Loading sub-app...</div>,
NotFoundComponent: () => <div>Sub-app not found</div>,
},
layout: ({ children, routeInfo, appEnter, appLeave }) => (
<div className="framework-layout">
<header>Framework Header</header>
<main>{children}</main>
<footer>Current route: {routeInfo.pathname}</footer>
</div>
),
}));Type alias for sub-application configuration, re-exported from @ice/stark.
/**
* Sub-application configuration type
* Re-exported from @ice/stark for convenience
*/
type AppConfig = CompatibleAppConfig;Interface describing route information passed to layout components.
/**
* Route information interface for framework layouts
*/
interface RouteInfo {
/** Current pathname */
pathname?: string;
/** Query parameters object */
query?: object;
/** URL hash value */
hash?: string;
/** Type of route transition */
routeType?: string;
}
/**
* Framework component type receiving route information
*/
type FrameworkComponent = ComponentType<RouteInfo>;The framework runtime automatically:
getApps() function to fetch sub-application configurationsWhen using a custom layout component, it receives these props:
interface LayoutProps {
/** Current route information */
routeInfo: RouteInfo;
/** Currently entered sub-application config */
appEnter: AppConfig;
/** Previously left sub-application config */
appLeave: AppConfig;
/** Function to update the apps list dynamically */
updateApps: (apps: AppConfig[]) => void;
/** Current pathname for convenience */
pathname: string;
/** Children components (the sub-application router) */
children: React.ReactNode;
}Important: Framework applications must provide a getApps function. The plugin will display a warning if this is missing:
[plugin-icestark]: appConfig.icestark.getApps should be not empty if this is an framework app.The appRouter configuration accepts most props from icestark's AppRouter, excluding:
onRouteChange (handled internally)onAppEnter (handled internally)onAppLeave (handled internally)Supported properties include:
ErrorComponent: Component shown when sub-app loading failsLoadingComponent: Component shown while sub-app is loadingNotFoundComponent: Component shown when route doesn't match any sub-appshouldAssetsRemove: Function to determine if sub-app assets should be removed