qiankun Micro-Frontend Solution

repository·next·Indexed 12 days ago

https://github.com/umijs/qiankun

A complete micro-frontend solution based on single-spa that enables building enterprise-ready web applications using multiple teams and different JavaScript frameworks. It provides features such as JS sandboxing, style isolation, and HTML entry streaming.

Tokens
110.1K
Snippets
247
Records
456
Agent score
96%

What's inside qiankun

  1. Overview of qiankun features

    next

    qiankun is a production-ready micro-frontend implementation based on single-spa. Key features include:

    • Technology Agnostic: Supports different JavaScript frameworks across sub-applications.
    • HTML Entry Access Mode: Uses import-html-entry to support loading sub-apps via HTML entry.
    • Isolation: Provides Style Isolation and JS Sandbox to ensure sub-applications are independent at runtime.
    • Performance: Supports Prefetch Assets to optimize loading.
    • Integration: Offers Umi Plugin integration for Umi users.
  2. What is qiankun and how does it work?

    next

    qiankun is a micro-frontend framework built on single-spa. It enables multiple independently developed and deployed front-end applications to coexist on a single page.

    Core Mechanism

    In a qiankun setup, a main app (the host) provides qiankun with a micro-app's HTML entry and an HTMLElement as a container. qiankun then loads the micro-app, mounts it into that container, and provides the main app with a handle to control the micro-app's lifecycle.

    Key Properties

    • Independent delivery: Micro-apps can be built and deployed on their own schedules.
    • Framework independence: Different technologies (React, Vue, Angular, etc.) can coexist.
    • Runtime composition: Applications are combined in the browser at runtime rather than during a shared build process.
    • Practical isolation: JavaScript is isolated by default via a sandbox, and styles can be isolated if enabled.
  3. Understand the two layers of @qiankunjs/sandbox

    next

    The @qiankunjs/sandbox package provides two distinct levels of isolation depending on your needs. You should choose based on whether you need only JavaScript isolation or full browser environment containment.

    1. Layer A: JS Isolation

      • Entry points: StandardSandbox (recommended for classic scripts) or Compartment (low-level mechanism).
      • Capabilities: Global write isolation, classic script evaluation, and ESM import() support.
      • Constraint: Has no assumptions about the DOM.
      • Warning: If using raw Compartment for classic scripts, window or self might not be automatically shadowed, leading to host pollution. Use StandardSandbox to avoid this.
    2. Layer B: Full Sandbox

      • Entry point: createSandbox().
      • Capabilities: Includes all Layer A capabilities plus DOM containment, style isolation, timer/listener recycling, and plugin lifecycles.
      • Requirement: Requires a container element.
  4. How the qiankun runtime model works

    next

    A qiankun micro-app instance follows a predictable lifecycle sequence managed by the host:

    1. loadMicroApp call: Initiates the process.
    2. Preparation: qiankun prepares the container and sets up isolation.
    3. Loading: The HTML entry and its associated assets are fetched.
    4. Bootstrap: The micro-app's bootstrap lifecycle function is called once.
    5. Mount: The micro-app's mount lifecycle function is called, rendering the app into the provided container.
    6. Observation/Control: The host uses the MicroApp handle to observe the state or trigger update or unmount operations.

    The HTML entry defines which scripts and styles belong to the app, and the micro-app is responsible for exporting valid lifecycle functions.

  5. Implement the micro app lifecycle contract

    next

    To be compatible with qiankun, a micro app must export three specific lifecycle hooks: bootstrap, mount, and unmount.

    • bootstrap: Called once when the application is being initialized.
    • mount: Called when the application is being mounted into the container. It receives props which includes the container element.
    • unmount: Called when the application is being removed from the container.
    let root;
    
    export async function bootstrap() {}
    
    export async function mount(props: { container: HTMLElement }) {
      root = render(props.container);
    }
    
    export async function unmount() {
      root.unmount();
    }
  6. Configure `<MicroApp>` settings and props

    next

    When using the <MicroApp> component in Vue, you can control the micro-app's environment and data flow using two specific props:

    1. settings: Accepts an AppConfiguration object. This is used to configure the qiankun engine itself, such as enabling or disabling the sandbox or specifying styleIsolation modes.
    2. appProps: An object used to pass reactive data from the host Vue application down into the micro-app. This is the primary mechanism for communication between the host and the child application.
  7. Guarantees and limitations of qiankun isolation

    next

    When using qiankun, keep the following technical constraints and guarantees in mind:

    • Container: The container must be a live HTMLElement. It should not be shared with unrelated host content.
    • Network/CORS: The entry URL and its assets must be reachable. Cross-origin deployments require correct CORS configuration.
    • Isolation: JavaScript isolation is provided by default. Style isolation is opt-in. Note that isolation is designed to reduce accidental interference; it is not a security boundary for running untrusted code.
    • Cleanup: While unmount() clears the rendered DOM and triggers the app's cleanup lifecycle, the micro-app is still responsible for releasing resources qiankun does not own, such as host-store subscriptions and Web Workers.
  8. Use the global argument in Lifecycle hooks

    next

    In lifecycle hooks, the global argument is the isolated WindowProxy view seen by that specific micro-app instance (when the default sandbox is enabled).

    Key distinctions:

    • It is not the micro-app's lifecycle object.
    • It is not the host page's real window.

    Best Practice: Use global only when a micro-app explicitly expects a value on its window view. For passing application data or callbacks, prefer using props instead.

  9. Handle ESM module lifecycle and remounting behavior

    next

    The ESM Sandbox introduces specific semantic differences regarding module execution:

    • Top-level Execution: ESM module top-level code executes only once. If a micro-app is remounted, the top-level code will not re-run. You should provide a migration guide or handle state resets within the mount lifecycle.
    • CSS-as-JS / Side Effects: Because top-level code doesn't re-run on remount, CSS-as-JS or other top-level side effects might disappear when an app is unmounted and remounted. Use patterns that allow for rebuilding CSS rules or re-evaluating side effects during the mount phase.
    • Unmounting and Cleanup: When an app is unmounted, qiankun calls dispose to clean up all associated Blob URLs and unregister the realm to prevent memory leaks.
  10. How HTML entries work in qiankun

    next

    A qiankun micro-app is defined by the URL of its HTML document (typically its index.html). When you pass this URL as the entry option to loadMicroApp, qiankun parses the document, follows the declared scripts and styles, and mounts the resulting application into the host container.

    This model allows the micro-app to remain the single source of truth for its own assets. Because the HTML document points to the hashed filenames produced by a build, the host does not need to maintain a separate asset manifest to stay in sync with new deployments.

    // Example of passing an HTML URL as an entry
    loadMicroApp({
      name: 'my-micro-app',
      entry: 'https://micro-app-domain.com/index.html',
    });
  11. Understand the ESM Sandbox for qiankun

    next

    The ESM Sandbox is a design proposal (RFC) for qiankun v3.x to support native ES Modules (ESM), specifically to enable compatibility with Vite dev mode without using iframes.

    Historically, qiankun relied on a 'classic script' model using with(this) to wrap code. However, with is a SyntaxError in ESM because ESM modules always run in strict mode. The ESM Sandbox solves this by using runtime rewriting via a CSP-safe JS lexer (es-module-lexer) and a global importmap to redirect module imports to sandboxed Blob URLs.

    Key Goals:

    • Native Developer Experience: Sub-apps use standard import/export and import.meta.url.
    • Sandbox Integrity: Global access is still constrained by the existing qiankun Membrane.
    • No iframes: Maintains the existing DOM sharing model.
    • No Build-time Plugins: Works with standard ESM production/dev builds without requiring specific compiler transformations.
  12. Detect qiankun environment using runtime flags

    next

    qiankun injects two specific flags into the sub-app's proxied window to allow the sub-app to adapt its behavior.

    • __POWERED_BY_QIANKUN__: A boolean flag (true) that allows the sub-app to detect if it is running within a qiankun container. This is useful for preventing self-rendering when the app is being managed by qiankun.
    • __INJECTED_PUBLIC_PATH_BY_QIANKUN__: A string containing the origin and directory of the app's entry. This is used to resolve the runtime public path for dynamic assets (like lazy-loaded chunks).

    Sub-apps should use __POWERED_BY_QIANKUN__ to decide whether to render immediately (standalone mode) or wait for qiankun to call the lifecycle hooks.

    if (window.__POWERED_BY_QIANKUN__) {
      // qiankun will call bootstrap/mount/unmount; don't self-render here
    } else {
      // standalone: render immediately
      render();
    }