文章转发自 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]';
}
复制代码
未完待续 ...