携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
前言
随着前端社区的飞速发展,微前端也被提及的越来越频繁,虽然现在很多公司都还没有运用到微前端,但是很多大厂已经将其投入生产了。所以,作为一名前端人员,我们或多或少应该要知道微前端这个东西。
概念
首先呢,微前端它不是一种技术,而是一种架构理念,其实早在2016年就已经有人提出。它的核心在于将单一的web应用拆解成多个可以独立开发、独立运行、独立部署的小型应用,并将他们整合为一个应用。微前端既可以将多个项目融为一个,又可以减少项目之间的耦合,提升项目的可扩展性,相比一整个前端仓库,微前端架构下的前端仓库倾向于更小更灵活。
微前端分为主应用和子应用,主应用也称为基座应用,是其它应用的容器载体,子应用则是被嵌入的一方,并且一个主应用可以包含多个子应用,子应用不受框架和技术限制。如下图所示:
常见的微前端方案
iframe
iframe应该算是我们前端最早接触的微前端方案,也都用过,相信大家都不陌生。iframe是所有微前端方案中最稳定的、上手难度最低的,但它肯定也有一些问题,比如性能低、通信复杂、有滚动条等,目前觉得iframe只适合简单的页面渲染,不适合做过于复杂的交互逻辑。
npm包管理
我们可以将子应用封装成npm包,通过组件的方式引入,在性能和兼容性上是最优的方案,但有一个问题就是版本更新,每次更新都需要主应用也跟着更新,管理起来可能非常麻烦。
微前端框架
目前市面上流行的微前端框架有single-spa、qiankun、MicroApp,相信大家或多或少都听过。 他们的特点如下:
- qiankun与single-spa都是通过监听url事件,在路由变化时匹配对应子应用进行渲染。
- qiankun与single-spa要求子应用修改渲染逻辑并暴露出三个方法:bootstrap、mount、unmount,分别对应初始化、渲染和卸载,这也导致子应用需要对入口文件进行修改。
- MicroApp借鉴了WebComponent的思想,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染。不需要暴露方法,也不需要修改webpack配置。
我在网上找了一张这三者的对比图
从上图可以看出,MicroApp的功能可能更加全面,于是乎呢,本人也亲自去实现了一个关于MicroApp的demo,实现起来确实要便捷很多,不需要过多的配置就能实现。demo的github地址我会放在文末。
关于MicroApp
介绍
MicroApp是京东的前端团队开源的一款微前端框架,点击前往官网
它的特点如下:
- 使用简单:将所有功能都封装到一个类WebComponent组件中,从而实现在主应用中嵌入一行代码即可渲染一个微前端应用。
- 零依赖:MicroApp没有任何依赖,这赋予它小巧的体积和更高的扩展性。
- 兼容所有框架:为了保证各个业务之间独立开发、独立部署的能力,MicroApp做了诸多兼容,在任何技术框架中都可以正常运行.
使用指南
以下案例主应用采用vue2+webpack,子应用也采用vue2+webpack。其他框架使用方式大同小异,可进官网查看文档。
作为主应用
强烈建议主应用采用history模式,hash路由的主应用只能加载hash路由的子应用,history模式的主应用对这两种子应用都支持。这里我们默认主应用的路由采用history模式。
- 安装依赖
npm i @micro-zoe/micro-app --save
- 在入口文件main.js中引入
// main.js
import microApp from '@micro-zoe/micro-app'
microApp.start()
- 修改publicPath
这一步借助了webpack的功能,避免子应用的静态资源使用相对地址时加载失败的情况,详情参考webpack文档 publicPath
// vue.config.js
module.exports = {
publicPath: '/main-vue2/', // 这里可以根据自己的需求随便定义
devServer: {
open: true, // 运行完成后自动打开浏览器
port: 8087, // 修改端口
}
}
- 分配一个路由给子应用
// router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
// 非严格匹配,/child-vue2/* 都指向 child-vue2 页面
path: '/child-vue2*',
name: 'child-vue2',
component: () => import('../views/child-vue2.vue'),
},
]
const router = new VueRouter({
mode:'history',
base: process.env.BASE_URL,
routes
})
export default router
- 在页面中嵌入子应用
<!--child-vue2.vue-->
<template>
<div>
<h1>子应用vue2</h1>
<!--
name(必传):子应用名称
url(必传):子应用地址
baseroute(可选):主应用分配给子应用的基础路由,就是上面的 `/child-vue2`
-->
<micro-app
name='child-vue2'
url='http://localhost:8088/child/vue2/'
baseroute='/main-vue2/child-vue2'>
</micro-app>
</div>
</template>
作为子应用
- 设置跨域支持
// vue.config.js
module.exports = {
publicPath: '/child/vue2/', // 这里可以根据自己的需求随便定义
devServer: {
port: 8088, // 修改端口
headers: {
'Access-Control-Allow-Origin': '*', // 设置跨域
},
}
}
- 设置基础路由(
如果主应用是history路由,子应用是hash路由,这一步可以省略)
// router.js
const router = new VueRouter({
mode: 'history',
// __MICRO_APP_BASE_ROUTE__ 为micro-app传入的基础路由
base: window.__MICRO_APP_BASE_ROUTE__ || process.env.BASE_URL,
routes,
})
- 设置publicPath
步骤1: 在子应用src目录下创建名称为public-path.js的文件,并添加如下内容
// __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
if (window.__MICRO_APP_ENVIRONMENT__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
步骤2: 在子应用入口文件的最顶部引入public-path.js
// main.js
import './public-path'
都配置完成以后,就可以把主应用和子应用跑起来查看效果了。
结尾
以上就是关于MicroApp的简单使用,更多的详细使用教程,请前往MicroApp官网进行查看。
如果大家配置不成功,可以去我的github仓库,查看我写的一个简单的demo ,其中主应用采用了vue2,子应用分别采用了vue2,vue3和react。
最后谢谢大家的观看,如有讲的不对的地方还请指正,谢谢!