Skip to content

loadMicroApp โ€‹

Manually load a micro application. This is useful for loading micro applications dynamically or when they are not associated with routing.

๐ŸŽฏ Function Signature โ€‹

typescript
function loadMicroApp<T extends ObjectType>(
  app: LoadableApp<T>,
  configuration?: AppConfiguration,
  lifeCycles?: LifeCycles<T>
): MicroApp

๐Ÿ“‹ Parameters โ€‹

app โ€‹

  • Type: LoadableApp<T>
  • Required: โœ…
  • Description: Micro application configuration

LoadableApp Structure โ€‹

typescript
interface LoadableApp<T extends ObjectType> {
  name: string;                    // Micro app name, globally unique
  entry: string | EntryOpts;       // Micro app entry
  container: string | HTMLElement; // Container for the micro app
  props?: T;                       // Custom data passed to micro app
}
PropertyTypeRequiredDescription
namestringโœ…Micro application name, used as unique identifier
entrystring | EntryOptsโœ…Micro application entry, can be URL or resource configuration
containerstring | HTMLElementโœ…Container node selector or DOM element
propsTโŒCustom data passed to the micro application

configuration โ€‹

  • Type: AppConfiguration
  • Required: โŒ
  • Description: Advanced configuration options
typescript
interface AppConfiguration {
  sandbox?: boolean;               // Enable sandbox isolation
  globalContext?: WindowProxy;     // Global context for the micro app
  fetch?: Function;                // Custom fetch function
  streamTransformer?: Function;    // Stream transformer
  nodeTransformer?: Function;      // Node transformer
}

lifeCycles โ€‹

  • Type: LifeCycles<T>
  • Required: โŒ
  • Description: Lifecycle hooks for this specific micro application

๐Ÿ”„ Return Value โ€‹

Returns a MicroApp instance with the following methods:

typescript
interface MicroApp {
  mount(): Promise<void>;          // Mount the micro app
  unmount(): Promise<void>;        // Unmount the micro app
  update(props: any): Promise<void>; // Update micro app props
  getStatus(): string;             // Get current status
  loadPromise: Promise<void>;      // Loading promise
  mountPromise: Promise<void>;     // Mounting promise
  unmountPromise: Promise<void>;   // Unmounting promise
}

๐Ÿ’ก Usage Examples โ€‹

Basic Usage โ€‹

typescript
import { loadMicroApp } from 'qiankun';

const microApp = loadMicroApp({
  name: 'manual-app',
  entry: '//localhost:8080',
  container: '#manual-container',
});

// The micro app will be automatically mounted

With Custom Props โ€‹

typescript
const microApp = loadMicroApp({
  name: 'dashboard',
  entry: '//localhost:8080',
  container: '#dashboard-container',
  props: {
    token: localStorage.getItem('token'),
    userId: getCurrentUserId(),
    theme: 'dark'
  }
});

With Configuration โ€‹

typescript
const microApp = loadMicroApp({
  name: 'third-party-app',
  entry: '//external.example.com',
  container: '#external-container',
}, {
  sandbox: false, // Disable sandbox for legacy apps
  fetch: customFetch, // Use custom fetch
});

With Lifecycle Hooks โ€‹

typescript
const microApp = loadMicroApp({
  name: 'monitored-app',
  entry: '//localhost:8080',
  container: '#monitored-container',
}, undefined, {
  beforeMount: (app) => {
    console.log('About to mount:', app.name);
    showLoadingSpinner();
  },
  afterMount: (app) => {
    console.log('Mounted successfully:', app.name);
    hideLoadingSpinner();
  },
  beforeUnmount: (app) => {
    console.log('About to unmount:', app.name);
    saveUserState();
  }
});

๐Ÿ”ง Advanced Usage โ€‹

Dynamic Loading with Conditions โ€‹

typescript
async function loadAppConditionally(condition: boolean) {
  if (condition) {
    const microApp = loadMicroApp({
      name: 'conditional-app',
      entry: '//localhost:8080',
      container: '#conditional-container',
    });
    
    return microApp;
  }
  return null;
}

Loading Multiple Apps โ€‹

typescript
function loadMultipleApps() {
  const apps = [
    { name: 'app1', entry: '//localhost:8001', container: '#container1' },
    { name: 'app2', entry: '//localhost:8002', container: '#container2' },
    { name: 'app3', entry: '//localhost:8003', container: '#container3' },
  ];

  const microApps = apps.map(app => loadMicroApp(app));
  return microApps;
}

Manual Control โ€‹

typescript
const microApp = loadMicroApp({
  name: 'controlled-app',
  entry: '//localhost:8080',
  container: '#controlled-container',
});

// Manual unmount
await microApp.unmount();

// Update props
await microApp.update({ newData: 'updated' });

// Check status
console.log(microApp.getStatus()); // 'MOUNTED', 'UNMOUNTED', etc.

๐ŸŽญ Use Cases โ€‹

1. Modal/Dialog Applications โ€‹

typescript
function openAppModal() {
  const modal = document.createElement('div');
  modal.id = 'app-modal';
  document.body.appendChild(modal);

  const microApp = loadMicroApp({
    name: 'modal-app',
    entry: '//localhost:8080',
    container: modal,
    props: { 
      onClose: () => {
        microApp.unmount().then(() => {
          document.body.removeChild(modal);
        });
      }
    }
  });

  return microApp;
}

2. Tab-based Applications โ€‹

typescript
class TabManager {
  private activeTabs = new Map<string, MicroApp>();

  async switchTab(tabName: string, config: LoadableApp) {
    // Unmount current active tab
    const currentApp = this.activeTabs.get('active');
    if (currentApp) {
      await currentApp.unmount();
    }

    // Load new tab
    const newApp = loadMicroApp({
      ...config,
      container: '#tab-content'
    });

    this.activeTabs.set('active', newApp);
    this.activeTabs.set(tabName, newApp);
  }
}

3. Widget System โ€‹

typescript
class WidgetSystem {
  loadWidget(widgetConfig: any) {
    return loadMicroApp({
      name: `widget-${widgetConfig.id}`,
      entry: widgetConfig.url,
      container: `#widget-${widgetConfig.id}`,
      props: widgetConfig.props
    }, {
      sandbox: true // Isolate widgets
    });
  }
}

โš ๏ธ Important Notes โ€‹

Container Management โ€‹

typescript
// โŒ Bad: Reusing containers without proper cleanup
loadMicroApp({ name: 'app1', entry: '//localhost:8001', container: '#shared' });
loadMicroApp({ name: 'app2', entry: '//localhost:8002', container: '#shared' }); // Conflict!

// โœ… Good: Use unique containers or proper cleanup
const app1 = loadMicroApp({ name: 'app1', entry: '//localhost:8001', container: '#container1' });
const app2 = loadMicroApp({ name: 'app2', entry: '//localhost:8002', container: '#container2' });

Memory Management โ€‹

typescript
// โœ… Good: Proper cleanup
const microApp = loadMicroApp({...});

// When done, always unmount
window.addEventListener('beforeunload', () => {
  microApp.unmount();
});

Error Handling โ€‹

typescript
try {
  const microApp = loadMicroApp({
    name: 'potentially-failing-app',
    entry: '//unreliable-server.com',
    container: '#container',
  });

  // Wait for load
  await microApp.loadPromise;
  console.log('App loaded successfully');
} catch (error) {
  console.error('Failed to load micro app:', error);
  // Handle error - show fallback UI, retry, etc.
}

๐Ÿ†š vs registerMicroApps โ€‹

FeatureloadMicroAppregisterMicroApps
LoadingManual, immediateAutomatic, route-based
Use CaseDynamic loading, widgets, modalsMain navigation, SPA routing
LifecycleManual controlAutomatic by routing
PerformanceLoad on demandCan preload

๐Ÿš€ Best Practices โ€‹

1. Resource Management โ€‹

typescript
class MicroAppManager {
  private apps = new Map<string, MicroApp>();

  async loadApp(config: LoadableApp) {
    // Check if already loaded
    if (this.apps.has(config.name)) {
      return this.apps.get(config.name);
    }

    const app = loadMicroApp(config);
    this.apps.set(config.name, app);
    
    // Auto cleanup on unmount
    app.unmountPromise.then(() => {
      this.apps.delete(config.name);
    });

    return app;
  }
}

2. Props Management โ€‹

typescript
// โœ… Good: Reactive props
function createReactiveMicroApp(baseConfig: LoadableApp) {
  let currentApp: MicroApp;

  return {
    async updateProps(newProps: any) {
      if (currentApp) {
        await currentApp.update(newProps);
      }
    },
    
    async reload(newConfig: LoadableApp) {
      if (currentApp) {
        await currentApp.unmount();
      }
      currentApp = loadMicroApp({
        ...baseConfig,
        ...newConfig
      });
    }
  };
}

3. Error Boundaries โ€‹

typescript
function loadMicroAppWithFallback(config: LoadableApp, fallbackHTML: string) {
  const microApp = loadMicroApp(config);
  
  microApp.loadPromise.catch((error) => {
    console.error('Micro app failed to load:', error);
    // Show fallback content
    const container = typeof config.container === 'string' 
      ? document.querySelector(config.container)
      : config.container;
    
    if (container) {
      container.innerHTML = fallbackHTML;
    }
  });

  return microApp;
}

Released under the MIT License.