前端單頁應用微服務化解決方案3 - 模塊加載器

文章轉發自 alili.techhtml

微前端的模塊加載器,主要功能爲:前端

  • 項目配置文件的加載
  • 項目對外接口文件的加載(消息總線會用到,後續會提)
  • 項目入口文件的加載

以上也是每個單模塊,不可缺乏的三部分git

配置文件

咱們實踐微前端的過程當中,咱們對每一個模塊項目,都有一個對外的配置文件. 是模塊在註冊到singe-spa時候所用到的信息.es6

{
    "name": "name", //模塊名稱
    "path": "/project", //模塊url前綴
    "prefix": "/module-prefix/", //模塊文件路徑前綴
    "main": "/module-prefix/main.js", //模塊渲染出口文件
    "store": "/module-prefix/store.js",//模塊對外接口
    "base": true 
    // 當模塊被定性爲baseApp的時候,
    // 無論url怎麼變化,項目也是會被渲染的,
    // 使用場景爲,模塊職責主要爲整個框架的佈局或者一直被渲染,不會改變的部分
  }
複製代碼

當咱們的模塊,有多種url前綴的時候,path也能夠爲數組形式github

{
    "path": ["/project-url-path1/","/project-url-path2/"], //項目url前綴
  }
複製代碼

配置自動化

咱們每一個模塊都有上面所描述的配置文件,當咱們的項目多個模塊的時候,咱們須要把全部模塊的配置文件聚合起來. 我這裏也有寫一個腳本.npm

micro-auto-configbootstrap

使用方法:數組

npm install micro-auto-config -g

# 在項目根目錄,用pm2啓動該腳本,即可啓動這個項目的配置自動化
pm2 start micro-auto-config
複製代碼

大概思路是:當模塊部署,服務器檢測到項目文件發生改變,便開始找出全部模塊的配置文件,把他們合併到一塊兒. 以數組包對象的形式輸出一個整體的新配置文件 project.config.js. 當咱們一個模塊配置有更新,部署到線上的時候,項目配置文件會自動更新.promise

模塊加載器

這個文件直接引入到html中,也就是上一篇文章中的single-spa-config.js 升級版. 在加載模塊的時候,咱們使用SystemJS做爲咱們的模塊加載工具.bash

"use strict";
import '../libs/es6-promise.auto.min'
import * as singleSpa from 'single-spa'; 
import { registerApp } from './Register'

async function bootstrap() {
    // project.config.js 文件爲全部模塊的配置集合
    let projectConfig = await SystemJS.import('/project.config.js' )

    // 遍歷,註冊全部模塊
    projectConfig.projects.forEach( element => {
        registerApp({
            name: element.name,
            main: element.main,
            url: element.prefix,
            store:element.store,
            base: element.base,
            path: element.path
        });
    });
    
    // 項目啓動
    singleSpa.start();
}

bootstrap()
複製代碼

Register.js

import '../libs/system'
import '../libs/es6-promise.auto.min'
import * as singleSpa from 'single-spa';

// hash 模式,項目路由用的是hash模式會用到該函數
export function hashPrefix(app) {
    return function (location) {
        let isShow = false
        //若是該應用 有多個須要匹配的路勁
        if(isArray(app.path)){
            app.path.forEach(path => {
                if(location.hash.startsWith(`#${path}`)){
                    isShow = true
                }
            });
        }
        // 普通狀況
        else if(location.hash.startsWith(`#${app.path || app.url}`)){
            isShow = true
        }
        return isShow;
    }
}

// pushState 模式
export function pathPrefix(app) {
    return function (location) {
        let isShow = false
        //若是該模塊 有多個須要匹配的路徑
        if(isArray(app.path)){
            app.path.forEach(path => {
                if(location.pathname.indexOf(`${path}`) === 0){
                    isShow = true
                }
            });
        }
        // 普通狀況
        else if(location.pathname.indexOf(`${app.path || app.url}`) === 0){
            isShow = true
        }
        return isShow;
    }
}

// 應用註冊
export async function registerApp(params) {

    singleSpa.registerApplication(params.name, () => SystemJS.import(params.main), params.base ? (() => true) : pathPrefix(params));

}

//數組判斷 用於判斷是否有多個url前綴
function isArray(o){
    return Object.prototype.toString.call(o)=='[object Array]';
}
複製代碼

未完待續 ...

相關文章

前端單頁應用微服務化解決方案1 - 思考

前端單頁應用微服務化解決方案2 - Single-SPA

前端單頁應用微服務化解決方案3 - 模塊加載器

前端單頁應用微服務化解決方案4 - 消息總線

前端單頁應用微服務化解決方案5 - 路由分發

前端單頁應用微服務化解決方案6 - 構建與部署

前端單頁應用微服務化解決方案7 - 靜態數據共享

前端單頁應用微服務化解決方案8 - 二次構建

Demo

前端微服務化 Micro Frontend Demo

微前端模塊加載器

微前端Base App示例源碼

微前端子項目示例源碼

相關文章
相關標籤/搜索