微前端架构是一种相似于微服务的架构,它将微服务的理念应用于浏览器端,即将Web应用从单一的单体应用转变为由多个小型前端应用聚合为一的应用。 现阶段实现微前端的方式大体有如下六种:javascript
Mooa
和 Single-SPA
Web Components
构建应用Web Components
构建这次实践,采用的是Single-SPA
的加载机制,具体以下。css
总体架构html
内项目 | 做用 |
---|---|
portal | 最上层路由分发框架 |
menu | 导航栏 |
cooper | 主体项目 |
projects | 有自定义西项目 |
.gitignore | git提交忽略配置 |
readme.md | 说明文档 |
portal: 路由分发机制源头,systemJs 和 single-spa 的使用。前端
portal项目启动为服务时,port设置成为了8233。vue
systemJs: 是一个 通用模块加载器,支持AMD、CommonJS、ES6等各类格式的JS模块加载,也是Angular2官推的加载器。因此该微前端实例,支持跨技术(react、angular)模块加载。java
single-spa: 是一个可让使用多个javascript语言框架的构建的应用集成在一块儿的框架。react
<script type="systemjs-importmap">{...}</script>
复制代码
用来导入能够须要引入的第三方模块,和插件。这里的config.js、single-spa.min.js、styles.css都是以HTTP形式引入,是为了不后续的路由问题,由于该html将做为模板直接复用。webpack
使用systemjs引入的方式git
System.import('@portal/config')
复制代码
引入single-spa模块web
registerApplication(名称,引入路径,是否引入)
singleSpa.start()启用
复制代码
用来判断某一模块是否引入
menu: 页面跳转
由于整个项目都是用vue写的,因此路由跳转这块用的是vue-router。
举例:
<router-link to="/index" />
复制代码
cooper: 页面响应 ***子项目由于使用vue-cli写的,因此 必定要引入vue-cli-plugin-single-spa插件,不然子项目的single-spa钩子没法正常exports。
vue项目中,先建立router.ts 举例:
import index from 'views/index/index.vue'
export default [{
path: '/index',
name: 'index',
component: index
}, ...]
复制代码
在app.vue 中
<router-view />
复制代码
那为何不一样项目之间路由会相应呢?
全部独立项目都是以single-spa的形式打包输出,并引入到portal架构下的,经systemjs引入以后,至关与是在portal下运行的一个项目,http衔接到了localhost:8233下。所以,在独立项目中引用图片、css文件是,也须要已http形式引入。避免合并到portal下后,路劲找不到的问题。
cooper/projects/menu: 入口文件配置
由于要打包成single-spa的形式,因此入口文件会有所不一样。
入口文件main.ts
import Vue from 'vue'
import singleSpaVue from 'single-spa-vue'
import App from './App.vue'
import store from './store'
import router from './router'
const vueLifecircle = singleSpaVue({
Vue,
appOption: {
el: '#vue',
render: r => r(App),
store,
router
}
})
复制代码
App.vue
<template>
<div id="vue">
<keep-alive>
<router-view />
</keep-alive>
</div>
</template>
...
复制代码
项目single-spa形式输出配置
以menu为例的独立项目打包配置vue.config.js
const path = require('path')
module.exports = {
chainWebpack: config => {
config.entryPoints.clear()
config.entry('menu').add('./src/main.ts').end()
config.output.filename('menu.js').library('menu').libraryTarget('amd').end()
config.devServer.port(8001).headers({
"Access-Control-Allow-Origin": "*"
})
},
outputDir: path.resolve(__dirname, 'dist/')
}
复制代码
输出的入口文件是menu.js,以AMD形式打包,缘由:single-spa是AMD形式,因此也是在portal项目中会引用amd.js的缘由。
portal项目打包配置
webppapck.config.config.js
module.export = {
entry: './src/config',
output: {
filename: 'config.js',
library: 'config',
libraryTarget: 'amd',
path: path.resolve(__dirname, 'build')
},
...
plugins: [
CopyWebpackPlugin([
{form: path.resolve(__dirname, 'src/index.html')},
{from: path.resolve(__dirname, 'src/style.css')},
{from: path.resolve(__dirname, 'common-deps-static')}
])
]
}
复制代码
只须要启动一个服务指向portal,其余子项目均放在portal目录下,以静态js文件形式引入。
能够把全部子项目的公共依赖所有提取,统一放到Portal层,已静态文件形式引入。一样,也能够把Vue、VueRouter、Vuex率先在portal层System.import(),而且注册为可用。详细细节后续会再整理一篇文档做为讲解。