文章轉發自 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()
複製代碼
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]';
}
複製代碼
未完待續 ...