N年前写的微前端笔记——模块加载器批量注册应用(三)

6.模块加载器

这里的模块加载器,其实主要就是通过汇集每个应用的配置文件,批量注册应用

配置文件

在每个应用下新建配置文件,比如在src/vue下新建config.js

export default {
  "name": "vue", //模块名称
  "path": "/vue-project", //模块url前缀
  "prefix": "/vue", //模块文件路径前缀
  "main": "vue/vue.app.js", //模块渲染出口文件
  "store": "./src/vue/store.js",//模块对外接口
  "base": false 
  // 当模块被定性为baseApp的时候,
  // 不管url怎么变化,项目也是会被渲染的,
  // 使用场景为,模块职责主要为整个框架的布局或者一直被渲染,不会改变的部分
}

聚合配置文件

将所有应用的配置文件汇总成一个数组

  • 在根目录下建project.config.js
import reactConfig from './src/react/config.js';
import vueConfig from './src/vue/config.js';

export default [
  reactConfig,
  vueConfig,
]

改造single-spa.config.js

我们原先写的single-spa.config.js的目的就是用于注册一个个应用,然后启动。那么由于已经拿到了所有应用的配置,所以可以通过改造,批量注册(其实就是数组遍历,low爆了)。

require('babel-polyfill')
import * as singleSpa from 'single-spa';
// 导入所有模块的配置集合
import projectConfig from './project.config.js';
import { registerApp } from './Register';
async function bootstrap(){
  // 批量注册:对所有模块依次注册
  projectConfig.forEach(config => {
    registerApp({
      name: config.name,
      main: config.main,
      url: config.prefix,
      store: config.store,
      base: config.base,
      path: config.path,
    })
  })
  singleSpa.start();
}

// 初始化,批量注册并启动
bootstrap();

我们可以看出,该文件的关键就是bootstrap函数,而该函数就是遍历总配置的数组,将每个应用的配置注入到registerApp函数中。那么这个registerApp函数用来干嘛的呢?显然,咱们这个文件的目的尚未实现——注册应用。所以,我们registerApp的代码主要就是注册应用。

  • 创建注册器文件Register.js

在这里,由于我们需要根据路由来判断加载哪个应用,所以需要考虑到路由的两种模式,hash和history模式。

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
        }
        console.log('hashPrefix', isShow)
        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, () => {
      return import(`./src/${params.main}`)
    }, params.base ? (() => true) : pathPrefix(params));

}

//数组判断 用于判断是否有多个url前缀
function isArray(o){
    return Object.prototype.toString.call(o)=='[object Array]';
}

至此,模块改造器就完成了。

启动

  • 此时,你启动npm start命令,就可以访问了
# 地址为/react时,只加载react应用
http://localhost:8080/react-project

# 地址为/vue时,只加载vue应用
http://localhost:8080/vue-project

# 地址为非/react-project或非/vue-project时,vue和react都不加载
http://localhost:8080/   (都不展示)
  • 在这里,需要注意的是:
    • 现在访问/react-project和/vue-project,不再是/react和/vue,因为我们在配置文件的path中规定了访问前缀
    • 现在访问除了/react-project和/vue-project之外的都不显示,不再像以前一样,访问/都显示,这是因为registerApplication第三个参数的函数中做了判断和限定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值