前言
- 这是我最近刚开始学微前端(qiankun框架)做的一个小demo,做的时候还是遇到很多问题的,在网上也是看了很多别人的Blog,最后也是磨出来了😂😂😂;
- 这篇文章总统分为分为两部分:
- 第一部分:是从0到1整个demo的搭建到启动的过程;
- 第二部分:在整个过程中遇到的各种问题解决和解决办法(后面会陆续补充)。
- 后面会出一个完整的微前端项目(一个基座 + 两个子应用(B站上面一些培训机构的项目))。
- 给孩子点点关注吧😭

一、demo 搭建 到 启动
1.1 创建 基座 和 微应用
- Vue创建项目的命令:
vue create 项目名称
- 各项目名称:
- 我是为方便,自己在每个项目下建立了
.env 文件,指定端口:
PORT = 指定端口号

- 各项目端口号:
- 如果项目中有 Eslint,可以先关闭:
- 在 vue.config.js 中:

1.2 qiankun 框架下载
- 只需要 基座 进行 qiankun的下载即可;
- 命令:
- npm:
npm i qiankun -S
- yarn:
yarn add qiankun
1.3 基座(主应用)配置
1.3.1 从 qiankun 引入两个函数
import { registerMicroApps, start } from 'qiankun'
1.3.2 注册微应用并启动
- 我自己是把以下代码前部写在
new Vue()前面的
- 注册 微应用:
registerMicroApps([
{
name: 'App2',
entry: '//localhost:3002',
container: '#container',
activeRule: '/app2'
},
{
name: 'App3',
entry: '//localhost:3003',
container: '#container',
activeRule: '/app3'
}
])
start()
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { start, registerMicroApps } from 'qiankun'
Vue.config.productionTip = false
registerMicroApps([
{
name: 'App2',
entry: '//localhost:3002',
container: '#container',
activeRule: '/app2'
},
{
name: 'App3',
entry: '//localhost:3003',
container: '#container',
activeRule: '/app3'
},
{
name: 'App4',
entry: '//localhost:8080',
container: '#container',
activeRule: '/login?redirect=%2F'
}
])
start()
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
1.3.3 基座(主应用)App.vue页面完整代码
<template>
<div id="app">
<nav>
<router-link to="/app2" style="color: blue; fontSize: 25px">App2 - Home</router-link> |
<router-link to="/app3" style="color: blue; fontSize: 25px">App3 - Home</router-link> |
</nav>
<div id="container"></div>
<router-view/>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
1.4 微应用配置
1.4.1 在 src下 新增 public-path.js 文件
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
1.4.2 微应用 入口文件(main.js) 配置
- 注意: 很多报错都是出在微应用入口文件的配置
- 在
router/index.js 中,有 new VueRouter() 这一步,注释掉 new VueRouter() 和 export default router,新增 export default routes(routes就是路由规则数组),就可以直接复制 qiankun官方 关于main.js代码直接使用, qiankun官方文档;

- 微应用
router/index,js 完整代码:
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import( '../views/AboutView.vue')
}
]
export default routes
import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/app2' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
1.4.3 微应用webpack配置
- 也是直接复制 qiankun官方的代码
- 在
vue.config.js 中配置
const { defineConfig } = require('@vue/cli-service')
const { name } = require('./package.json');
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${name}`,
},
},
})
1.4.3. 微应用App.vue代码
<template>
<div id="app">
<nav>
<h1 style="color: red; fontSize: 50px">App2 - 我是 3002 端口</h1>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
<template>
<div id="app">
<nav>
<h1 style="color: red; fontSize: 50px">App3 - 我是 3003 端口</h1>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
二、过程中遇到的问题及解决方法
2.1 需要从微应用中导出生命周期函数
- 错误:
application 'misthin-admin-element' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in misthin-admin-element entry
- 解决办法:
- 首先去官方看看:qiankun官方常见问题
- 如果配置什么的都没有问题,还是报这个错误,我自己这边还是 webpack的问题:
module.exports = defineConfig({
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${name}`,
},
},
})
module.exports = {
configureWebpack: (config) => {
config.output.library = `${name}-[name]`
config.output.libraryTarget = 'umd'
config.output.jsonpFunction = `webpackJsonp_${name}`
config.output.globalObject = 'window'
}
};
2.2 关于webpack的报错
- 在 webpack4 中,多个 webpack 运行时可能会在同一个 HTML 页面上发生冲突,因为它们使用同一个全局变量进行代码块加载。为了解决这个问题,需要为
output.jsonpFunction 配置提供一个自定义的名称。
- Webpack5 确实会从 package.json name 中自动推断出一个唯一的构建名称,并将其作为 output.uniqueName 的默认值。
- 这个值用于使所有潜在的冲突的全局变量成为唯一。
- 迁移: 由于 package.json中有唯一的名称,可将
output.jsonpFunction 删除。
- 报错原因: 在2020-10-10发布的webpack5中已将
output.jsonpFunction 更名为 output.chunkLoadingGlobal

2.3 关于项目静态资源加载404问题

- 问题出现原因:
- 微应用(子应用)放入到基座(主应用)中后,静态资源会默认走主应用地址去访问,但是主应用中又没有这些静态资源文件,其结果显而易见,肯定就是404了。
- 解决方法:
- 原理:
publicPath字段设置静态资源路径,默认是走的相对路径,将该字段配置成绝对地址的url即可(子应用部署之后的地址,本地调试的时候,写本地服务地址即可)。
- 解决方法:
module.exports = {
publicPath: 'http://localhost:8080',
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`
}
},
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
}
publicPath配置选项在各种场景中都非常有用,可以通过它来指定应用程序中所有资源的基础路径。
2.4 其他错误