微前端在Vue项目的实践
文章的参考:微前端在美团外卖的实践我将讲解微前端如何在Vue项目中实践和应用,业务逻辑参考文中介绍的,文章中介绍的逻辑比较清晰,但是并没有提供过多的业务代码,对微前端如何应用到具体的项目我们就无从而知,为了介绍如何应用到项目中,我就写下了这篇文章,我们应用的工程是在Vue项目中。如果你还不知道如何通过webpack配置Vue项目,请先参考这篇文章:自己搭建一个Vue项目工程我的微前端项目...
文章的参考:微前端在美团外卖的实践
我将讲解微前端如何在Vue项目中实践和应用,业务逻辑参考文中介绍的,文章中介绍的逻辑比较清晰,但是并没有提供过多的业务代码,对微前端如何应用到具体的项目我们就无从而知,为了介绍如何应用到项目中,我就写下了这篇文章,我们应用的工程是在Vue项目中。
- 如果你还不知道如何通过webpack配置Vue项目,请先参考这篇文章:自己搭建一个Vue项目工程
我的微前端项目是基于自己配置的webpack项目,不再使用Vue官方脚手架,因为生成出来的项目不服务我们的预期,比如有些要打包,有些不打包,等等。
如何使用
基座工程和子工程启动命令都是yarn dev
,两个工程必须都要启动,基座工程提供运行的环境,子工程负责打包自己的项目供外界访问,两个服务链接的桥梁是JSONP。
基座提供了一个注册子工程的入口文件:app.json
{
"web": {
"js": "http://localhost:9000/app.js"
}
}
表示我们的子项目启动在http://localhost:9000/
这个服务上,app.js表示子项目的入口文件,当访问到子工程的某个项目的时候,会发送一个JSONP请求到子工程服务器中,拿到对应的JS脚本执行即可,因为我们的微前端是基于路由划分的,(当然你也可以基于组件跟加细致的划分等等,但是对项目改动太大了,不适合已经开放了的项目),下面看加载子项目的代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import { handleRouter } from './generator'
import Store from '../store'
import jsonp from 'jsonp'
const subAppMapInfo = require('../../app.json')
Vue.use(VueRouter)
const routes = [
{
path: '/subapp',
name: 'Home',
component: Home
},
{
path: '/',
redirect: '/subapp'
}
]
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
const subAppRoutes = {}
router.beforeEach(function (to, from, next) {
const { path } = to;
const id = path.split('/')[2];
const subAppModule = subAppMapInfo[id];
if (subAppModule) {
if (subAppRoutes[id]) {
if (subAppRoutes[id].beforeEach) {
let Route = router
Route.handleRouter = handleRouter
Route.cacheRouter = routes
subAppRoutes[id].beforeEach(to, from, next, Store, Route)
} else {
next()
}
} else {
jsonp(subAppMapInfo[id].js, { timeout: 500 }, function (err, date) {
if (err) {
console.log(`${id}项目加载失败:`, err)
next('/subapp')
} else {
let result = date()
console.log(`${id}项目加载成功:`, result)
// 加载路由
subAppRoutes[id] = result
let children = routes[0].children
if (children) {
routes[0].children = children.concat(handleRouter({name: id, router: result.router}))
} else {
routes[0].children = handleRouter({name: id, router: result.router})
}
router.addRoutes(routes)
// 加载状态
Store.registerModule(id, result.store)
next({...to, replace:true})
}
})
next()
}
} else {
next()
}
})
export default router
JSONP获取之后会执行脚本,会传入一个registerApp
函数,表示注册APP的函数,这个函数提供了当前APP需要的路由信息和状态容器,这个信息将会注册在基座工程里面,基座工程就会添加到基座工程的路由里面,就可以访问了。
import router from './router'
import store from './store'
function registerApp () {
return {
router, // 子项目的router
store, // 子项目的store
beforeEach (to, from, next) {
next()
}
}
}
try {
// eslint-disable-next-line no-undef
__jp0(registerApp, '将注册函数返回让外界调用')
} catch (error) {
console.log(error)
}
export default registerApp
大家还是参考代码实现把:
更多推荐
所有评论(0)