微前端架構是一種相似於微服務的架構,它將微服務的理念應用於瀏覽器端,即將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(),而且註冊爲可用。詳細細節後續會再整理一篇文檔做爲講解。