How Guming Built a Zero‑Config Micro‑Frontend Architecture for Its Backend Systems

This article explains how Guming's frontend team unified development across multiple backend subsystems by abandoning qiankun, defining strict routing and deployment conventions, automating enforcement through a custom build tool, and providing SDKs, sandboxing, and local development support to boost efficiency and user experience.

Goodme Frontend Team
Goodme Frontend Team
Goodme Frontend Team
How Guming Built a Zero‑Config Micro‑Frontend Architecture for Its Backend Systems

Introduction

Guming previously published an article about its frontend work, which covered web, H5, mini‑programs, Electron, and Android/Flutter clients. To support these diverse fronts, the team needed common capabilities and deep technical accumulation for each domain, focusing here on the backend side.

Business Status

The company operates many backend subsystems—permission, membership, product, expansion, operation, finance, store, supply chain—serving internal products, technology, operations, and external franchisees. These subsystems are maintained by different teams without systematic technical consolidation, creating challenges for fast, high‑quality delivery as scale and complexity grow.

Technical Evolution

The architecture evolved through four stages: a single‑app mode, splitting into multiple subsystems with SystemJS (early micro‑frontend), adopting qiankun for version isolation, and finally abandoning qiankun for a fully self‑developed solution.

Why Abandon qiankun?

Qiankun is a micro‑frontend framework that only manages sub‑applications. It introduced issues such as unresponsive routes after navigation, bugs from third‑party libraries, and limitations like entry configuration, style isolation, deployment, route conflicts, and cross‑origin requirements, which could not be solved by qiankun alone.

Exploration Direction

The team identified two main goals: R&D efficiency and user experience . The first step is unification , establishing a clear architectural foundation.

Architecture Design

The overall design follows two principles: “unify” and “standardize”, aiming to improve the team’s development efficiency. A good architecture should have clear boundaries, avoiding unnecessary feature stacking.

Naming the Solution

The architecture suite is named Mars . All related NPM packages, component libraries, SDKs, and deployment paths use the mars keyword, fostering shared recognition and reducing communication overhead.

Framework Design

The framework follows a micro‑frontend approach similar to mainstream solutions. When a user accesses the site, the gateway loads the base layout and menu from the base app, then renders the appropriate sub‑application and page on route changes.

Unlike many micro‑frontend frameworks that require manual configuration of name, entry, and activeRule for each sub‑app, Mars adopts a zero‑configuration strategy based on convention routing and deployment paths.

Convention Routing and Deployment Paths

Routing Convention

The standard Mars route format is:

/mars/appId/path/some?name=ferret
_/   _/   \_____/   \_______/
 |     |       |          |
标识  appId   path       query

Routes must start with /mars for backward compatibility.

The next segment appId uniquely identifies the sub‑application.

The final path and query represent the business route and parameters.

Deployment Path Convention

The standard manifest URL is:

https://cdn.example.com/mars/[appId]/[env]/manifest.json
__________________/  \_/   \___/   \_/   \________/
          |            |      |      |        |
       cdn domain      标识   appId  env   entry manifest

Because env is known at release time, the full URL can be derived from appId. The route convention allows extracting appId to locate the corresponding manifest.json and load the sub‑app’s resources.

Compiling Applications

To enforce conventions, the team uses a compilation step. The internal tool @guming/kone-plugin-mars registers the sub‑app’s appId and processes a kone.config.json file:

{
  "plugins": ["@guming/kone-plugin-mars"],
  "mars": {
    "appId": "demo"
  }
}

The compiler reads src/app.json, generates route definitions, registers mount and unmount lifecycle methods, and produces a manifest.json containing JS and CSS entry URLs.

{
  "js": ["https://cdn.example.com/mars/demo/prod/app.a0dd6a27.js"],
  "css": ["https://cdn.example.com/mars/demo/prod/app.230ff1ef.css"]
}

Sandbox Isolation

The team decided that JS isolation is unnecessary, but CSS isolation is essential. A PostCSS plugin prefixes all CSS selectors with a unique namespace (e.g., .mars__demo .red { color: red; }). Global styles can be exempted using the :global selector.

.red { color: red; }
/* compiled */
.mars__demo .red { color: red; }

When a sub‑app is unloaded, its associated CSSStyleSheet is disabled to prevent leftover styles.

if (this.sheet) {
  this.sheet.disabled = true;
}

SDK Design

The SDK is divided into three categories: sub‑application, base‑application, and compiler. APIs are unified; for example, routing is provided only through mars.navigate and mars.getLocation, while other routing libraries are blocked at compile time.

import { mars } from '@guming/mars';

// navigate to /mars/demo/some/detail?a=123
mars.navigate('/mars/demo/some/detail', { params: { a: '123' } });

const { pathname, params } = mars.getLocation();
// pathname: /mars/demo/some/detail
// params: { a: '123' }

A syntax sugar allows using : as a shortcut for the /mars/[appId] prefix within a sub‑app.

mars.navigate(':/some/detail', { params: { a: '123' } });

Local Development Experience

Development Simulator

A local simulator automatically starts a mock base app when a sub‑app runs, providing a near‑identical layout, environment, and login integration. It also offers a debug widget to modify proxy rules on the fly.

IDE Support

WebStorm and VSCode plugins deliver route component path completion, click‑to‑navigate, and configuration validation. JSON schema files enable auto‑completion and error checking in editors.

Historical Project Migration

To migrate twelve legacy projects to the new architecture, the team allocated two developers for two months. They defined clear migration boundaries—unifying React, React‑DOM, Ant Design versions, routing, request library, engineering system, and environment variables.

Define Goals

A migration plan was created, emphasizing speed and scope limitation.

Refine SOP

A detailed SOP document was drafted, covering all scenarios and solutions, iteratively improved as pilot projects revealed missing cases.

Migration Example

Legacy projects using the DVA framework had coupled router and model. The team hacked DVA’s source to inject the model before the app, decoupling it from the router and enabling the unified routing scheme.

Release Strategy

From branch creation to production, the entire process should be completed within one week to minimize merge conflicts and ensure code quality through regression testing, rollback plans, and communication.

Conclusion

There is no perfect solution, only the one that fits your team. The Mars architecture reflects Guming’s current needs and may inspire other teams seeking efficient, unified frontend development for complex backend systems.

frontendArchitecturebuild automationmicro-frontend
Goodme Frontend Team
Written by

Goodme Frontend Team

Regularly sharing the team's insights and expertise in the frontend field

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.