An completed implementation of Micro Frontends
npm install @zstack/qiankun   
> In Chinese traditional culture qian means heaven and kun stands for earth, so qiankun is the universe.
An implementation of Micro Frontends, based on single-spa, but made it production-ready.
As we know what micro-frontends aims for:
> Techniques, strategies and recipes for building a modern web app with multiple teams using different JavaScript frameworks. — Micro Frontends
An independent development experience is very important for a large system, especially with an enterprise application. But if you've tried to implement a micro-frontends architecture in such a system, you'll usually hurt your brain with such problems:
- How to compose your independent sub apps into your main system?
- How to guarantee your sub apps to be isolated by each other?
- and so on...
We built an library to help you solve these glitch problems automatically without any mental burden of yours, then named it qiankun.
Probably the most complete micro-frontends solution you ever met🧐.
``shell`
$ yarn add qiankun # or npm i qiankun -S
`ts
import { registerMicroApps, start } from 'qiankun';
function render({ appContent, loading }) {
const container = document.getElementById('container');
ReactDOM.render(
}
function genActiveRule(routerPrefix) {
return location => location.pathname.startsWith(routerPrefix);
}
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:7100',
render,
activeRule: genActiveRule('/react'),
},
{
name: 'vue app',
entry: { scripts: ['//localhost:7100/main.js'] },
render,
activeRule: genActiveRule('/vue'),
},
]);
start();
`
`ts
export async function bootstrap() {
console.log('react app bootstraped');
}
export async function mount(props) {
console.log(props);
ReactDOM.render(
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('react15Root'));
}
`
For more lifecycle information, see single-spa lifecycles
While you wanna build a sub app to integrate to qiankun, pls make sure your bundler have the required configuration below:
#### webpack:
`js
const packageName = require('./package.json').name;
module.exports = {
output: {
library: ${packageName}-[name],webpackJsonp_${packageName}
libraryTarget: 'umd',
jsonpFunction: ,`
},
};
see https://webpack.js.org/configuration/output/#outputlibrary
#### parcel:
`shell`
parcel serve entry.js --global myvariable
see https://en.parceljs.org/cli.html#expose-modules-as-umd
`shell`
$yarn
$yarn install:examples
$yarn start
Visit http://localhost:7099

- Based on single-spa
- HTML Entry
- Config Entry
- Isolated styles
- JS Sandbox
- Assets Prefetch
- @umijs/plugin-qiankun integration
`typescript
function registerMicroApps
apps: Array
lifeCycles?: LifeCycles
opts?: RegisterMicroAppsOpts,
): void;
type RegistrableApp = {
// name to identify your app
name: string;
// where your sub app served from, supported html entry and config entry
entry: string | { scripts?: string[]; styles?: string[]; html?: string };
// render function called around sub app lifecycle
render: (props?: { appContent: string; loading: boolean }) => any;
// when sub app active
activeRule: (location: Location) => boolean;
// props pass through to sub app
props?: object;
};
type Lifecycle
type LifeCycles
beforeLoad?: Lifecycle
beforeMount?: Lifecycle
afterMount?: Lifecycle
beforeUnmount?: Lifecycle
afterUnmount?: Lifecycle
};
`
`typescript`
function start(options: Options): void;
Options
| param | description | default |
| --- | --- | --- |
| prefetch | Whether to prefetch assets of sub apps after first sub app mounted | true |
| jsSandbox | While sandbox enabled, we could guarantee that sub apps is isolated with each others | true |
| singular | Only one sub app display at one runtime, that means a sub app will wait to mount until the before one unmounted | true |
| fetch | Set a custom fetch function | window.fetch |
Set which sub app shoule be active by default after master loaded.
`typescript`
function setDefaultMountApp(defaultAppLink: string): void;
`typescript``
function runAfterFirstMounted(effect: () => void): void;
- [ ] Parcel apps integration (multiple sub apps displayed at the same time, but only one uses router at most)
- [ ] Communication development kits between master and sub apps
- [ ] Custom side effects hijacker
- [ ] Nested Microfrontends
https://github.com/umijs/qiankun/wiki/FAQ
https://github.com/umijs/umi#community
or

- single-spa What an awesome meta-framework for micro-frontends!