前言
这是我最近刚开始学微前端(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 基座(主应用)配置
qiankun官方 主应用配置 以下注册都是在 main.js
中配置的。
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 其他错误
我主要遇到的就是这个问题,其他的错误可以移步 qiankun官方常见问题; 还有一种可能就是 eSlint导致的。