vue-cli、ts + single-spa + systemJs 實現微前端

微前端架構是一種相似於微服務的架構,它將微服務的理念應用於瀏覽器端,即將Web應用從單一的單體應用轉變爲由多個小型前端應用聚合爲一的應用。 現階段實現微前端的方式大體有如下六種:javascript

  1. 使用 HTTP 服務器的路由來重定向多個應用
  2. 在不一樣的框架之上設計通信、加載機制,諸如 MooaSingle-SPA
  3. 經過組合多個獨立應用、組件來構建一個單體應用
  4. iFrame。使用 iFrame 及自定義消息傳遞機制
  5. 使用純 Web Components 構建應用
  6. 結合 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>
...
複製代碼

webpack配置明細

項目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(),而且註冊爲可用。詳細細節後續會再整理一篇文檔做爲講解。

相關文章
相關標籤/搜索