微前端 Micro-Frontnds - Single-SPA Application API

Application API

import { registerApplication, start } from 'single-spa';
// or
import * as singleSpa from 'single-spa';

registerApplication

使用在 root config 中,用于注册应用
Simple arguments

singleSpa.registerApplication('app-name',() => System.import('appName'),location => location.pathname.startsWith('app')
)

Arguments
- appName: string 应用的名称
- applicationOrLoadingFn:() => <Function | Promise> 一个返回应用或 Promise 的函数
- activeFn: (location) => boolean 纯函数,以 window.location 为参数,返回true 表示激活该应用,false 表示卸载该应用
- customProps?: Object | () => Object 可选,需要传递给应用生命周期钩子的自定义参数

Configuration Object

singleSpa.registerApplication({name: 'app-name',app: () => System.import('appName'),activeWhen: '/app',customProps: {authToken: 'xxxxx'}
})

Arguments
- name: string 应用的名称
- app: Application | () => Application | Promise 应用
- activeWhen: string | (location) => boolean | (string | (location) => boolean)[] 什么时候激活应用与上面的一样
- customProps?: Object | () => Object 可选,需要传递给应用生命周期钩子的自定义参数

start

让 single-spa 对应用进行控制,让您可以控制单页应用程序的性能

singleSpa.start()singleSpa.start({urlRerouteOnly: true
})

Arguments
一个可选的对象,这个对象有 urlRerouteOnly 属性
urlRerouteOnly:一个默认为false的布尔值。如果设置为true,则除非更改了客户端路由,否则对history.pushState()和history.replaceState()的调用将不会触发单spa重新路由。在某些情况下,将此值设置为true可能会更好。

triggerAppChange

手动触发 single-spa 加载应用

singleSpa.triggerAppChange();

navigatToUrl

在已注册的应用之间执行 url 导航,而不需要处理 event.preventDefault() pushState triggerAppChange

// Three ways of using navigateToUrl
singleSpa.navigateToUrl("/new-url");
singleSpa.navigateToUrl(document.querySelector('a'));
document.querySelector('a').addEventListener(singleSpa.navigateToUrl);

Arguments
navigationObj: string | context | DOMEvent
- url 字符串
- 带有 href 属性的标签,例如 a 标签
- 一个具有href属性的DOMElement上的click事件的DOMEvent对象;

getMountedApps

获取挂载(MOUNTED)应用的名字,返回一个字符串数组

const mountedAppNames = singleSpa.getMountedApps();
console.log(mountedAppNames); // ['app1', 'app2', 'navbar']

getAppNames

获取所有注册的应用,与应用的状态无关

const appNames = singleSpa.getAppNames();
console.log(appNames); // ['app1', 'app2', 'app3', 'navbar']

getAppStatus

获取指定应用的状态

const status = singleSpa.getAppStatus('app1');
console.log(status); // one of many statuses (see list below). e.g. MOUNTED

Arguments
appName: string 注册应用的名字

Returns
appStatus: string | null , null 表示应用不存在
- NOT_LOADEDapp :应用已经注册,但是还没有加载好
- LOADING_SOURCE_CODE:已经获取到源代码
- NOT_BOOTSTRAPPED: 应用已经加载好,但是还没开始初始化
- BOOTSTRAPPING:已经调用 bootstrap 生命周期钩子,但是还没执行完
- NOT_MOUNTED:已经执行好 bootstrap ,但是还没挂载
- MOUNTING:正在执行 mount 钩子
- MOUNTED:应用已经挂载在 DOM 上了
- UNMOUNTING:正在执行 unmount
- UNLOADING:正在执行 unloading
- SKIP_BECAUSE_BROKEN:应用在加载,引导,安装或卸载期间引发了错误,并且由于行为不当而被跳过,因此已被隔离。其他应用将继续正常运行。
- LOAD_ERROR:应用在 loading 方法中返回了 reject 的 Promise,这通常是由于尝试下载应用程序的JavaScript软件包的网络错误。

unloadApplication

卸载已注册的应用程序的目的是将其设置回NOT_LOADED状态,这意味着它将在下次需要安装时重新引导。这样做的主要用例是允许热重载整个已注册的应用程序,但是无论何时您要重新引导应用程序,unloadApplication都会很有用。

// Unload the application right now, without waiting for it to naturally unmount.
singleSpa.unloadApplication('app1');// Unload the application only after it naturally unmounts due to a route change.
singleSpa.unloadApplication('app1', {waitForUnmount: true});

当调用 unloadApplication 后 Single-spa 会执行如下几步
1. 在要卸载的注册应用程序上调用卸载生命周期。
2. 设置 App 状态为 NOT_LOADED
3. 触发重新路由,在这期间 single-spa 会挂载刚卸载的应用
因为调用unloadApplication时可能会挂载已注册的应用程序,所以您可以指定是要立即卸载还是要等待直到不再挂载该应用程序。这是通过waitForUnmount选项完成的。

Arguments
appName: string 应用名称
Options?: { waitForUnmoun: boolean = false} 可选对象参数,默认 single-spa 会立即卸载指定应用,如果设置为 true,single-spa 会等应用不处于 MOUNTED 状态的时候进行卸载。

unregisterApplication

unregisterApplication函数将卸载,卸载和注销应用程序,一旦调用,应用不会再挂载

import { unregisterApplication } from 'single-spa';unregisterApplication('app1').then(() => {console.log('app1 is now unmounted, unloaded, and no longer registered!');
})
- Unregistering 应用程序不会将其从SystemJS模块注册表中删除。
- Unregistering 应用程序不会从浏览器内存中删除其代码或javascript框架。
- Unregistering 应用程序的另一种方法是在应用程序的活动功能内执行权限检查。这具有防止应用程序挂载的类似效果。

Arguments
appName: string 应用名称

checkActivityFunctions

将使用模拟窗口位置调用每个应用程序的活动函数,并提供应在该位置挂载哪些应用程序的列表。

const appsThatShouldBeActive = singleSpa.checkActivityFunctions();
console.log(appsThatShouldBeActive); // ['app1']const appsForACertainRoute = singleSpa.checkActivityFunctions({pathname: '/app2'});
console.log(appsForACertainRoute); // ['app2']

Arguments
mockWindowLocation: string 表示window.location的字符串,将在调用每个应用程序的活动函数以测试它们是否返回true时使用。

Returns
appNames: string[] 返回符合的应用名称的数组

addErrorHandler

在生命周期函数或者激活函数中报错的时候会执行该方法,如果没有这个处理函数,就会直接抛出到窗口

singleSpa.addErrorHandler(err => {console.log(err);console.log(err.appOrParcelName);console.log(singleSpa.getAppStatus(err.appOrParcelName));
});

Arguments
errorHandler: Function(error: Error) 将通过Error对象调用,该对象还具有message和appOrParcelName属性。

removeErrorHandler

移除错误处理函数

singleSpa.addErrorHandler(handleErr)
singleSpa.removeErrorHandler(handleErr)function handleErr(err) {console.log(err)
}

Arguments
errorHandler: Function 函数名称

Returns
Boolean :true 表示移除成功

mountRootParcel

创建并挂载一个 singel-spa parcel

// Synchronous mounting
const parcel = singleSpa.mountRootParcel(parcelConfig, {prop1: 'value1', domElement: document.getElementById('a-div')});
parcel.mountPromise.then(() => {console.log('finished mounting the parcel!')
})// Asynchronous mounting. Feel free to use webpack code splits or SystemJS dynamic loading
const parcel2 = singleSpa.mountRootParcel(() => import('./some-parcel.js'), {prop1: 'value1', domElement: document.getElementById('a-div')});

Arguments
parcelConfig: object | loading Function
parcelProps: object 具有 DOM 元素属性的对象

returns
Parcel object

pathToActiveWhen

pathToActiveWhen 函数将字符串URL路径转换为活动函数。字符串路径可能包含 single-spa 匹配任何字符的路由参数。假定提供的字符串是前缀。
当在注册应用的时候给 ativeWhen 传递一个字符串时会被调用
Arguments
Path: string url 的前缀
returns: (location: location) => boolean
Examples

let activeWhen = singleSpa.pathToActiveWhen('/settings');
activewhen(new URL('http://localhost/settings')); // true
activewhen(new URL('http://localhost/settings/password')); // true
activeWhen(new URL('http://localhost/')); // falseactiveWhen = singleSpa.pathToActiveWhen('/users/:id/settings');
activewhen(new URL('http://localhost/users/6f7dsdf8g9df8g9dfg/settings')); // true
activewhen(new URL('http://localhost/users/1324/settings')); // true
activewhen(new URL('http://localhost/users/1324/settings/password')); // true
activewhen(new URL('http://localhost/users/1/settings')); // true
activewhen(new URL('http://localhost/users/1')); // false
activewhen(new URL('http://localhost/settings')); // false
activeWhen(new URL('http://localhost/')); // falseactiveWhen = singleSpa.pathToActiveWhen('/page#/hash');
activeWhen(new URL('http://localhost/page#/hash')); // true
activeWhen(new URL('http://localhost/#/hash')); // false
activeWhen(new URL('http://localhost/page')); // false

ensureJQuerySupport

用于保障不同版本的 jQuery 的 event delegation

Arguments
jQuery? : JQueryFn = window.jQuery 对jQuery已绑定到的全局变量的引用

setBootstrapMaxTime

设置全局 bootstrap 的超时时间

// After three seconds, show a console warning while continuing to wait.
singleSpa.setBootstrapMaxTime(3000);// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setBootstrapMaxTime(3000, true);// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setBootstrapMaxTime(3000, true, 10000);

Arguments
Mills: number 超时之前等待 bootstrap 完成的毫秒数。
dieOnTimeout: boolean = false 如果为false,则已注册的应用程序会使速度降低,直到达到 mills 之前,只会在控制台中引起一些警告。如果为true,则使已注册应用程序将被置为 SKIP_BECAUSE_BROKEN 状态,在此状态下,它们将再也没有机会改变内容。
warningMillis: number = 1000 在最终超时之前发生的控制台警告之间等待的毫秒数。

setMountMaxTime

设置全局 mount 的超时时间

// After three seconds, show a console warning while continuing to wait.
singleSpa.setMountMaxTime(3000);// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setMountMaxTime(3000, true);// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setMountMaxTime(3000, true, 10000);

Arguments
同上

setUnmountMaxTime

设置全局 unmount 的超时时间

// After three seconds, show a console warning while continuing to wait.
singleSpa.setUnmountMaxTime(3000);// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setUnmountMaxTime(3000, true);// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setUnmountMaxTime(3000, true, 10000);

Arguments
同上

setUnloadMaxTime

设置 unload 的超时时间

// After three seconds, show a console warning while continuing to wait.
singleSpa.setUnloadMaxTime(3000);// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setUnloadMaxTime(3000, true);// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setUnloadMaxTime(3000, true, 10000);

Arguments
同上

Event

single-spa 将事件触发到窗口,作为您的代码挂接到URL过渡的一种方式

PopStateEvent

当 single-spa 想要所有激活的应用重新渲染时,通过该事件触发。当一个应用程序调用history.pushState,history.replaceState或triggerAppChange时,就会发生这种情况。

window.addEventListener('popstate', evt => {if (evt.singleSpa) {console.log('This event was fired by single-spa to forcibly trigger a re-render')console.log(evt.singleSpaTrigger); // pushState | replaceState} else {console.log('This event was fired by native browser behavior')}
});

Canceling navigation

取消导航是指更改URL,然后立即将其更改回之前的状态。这个发生在 mounting 、unmounting 或者 loading 之前完成。可以与Vue路由器和Angular路由器的内置导航保护功能结合使用,这些功能可以取消导航事件。

// 监听 single-spa:before-routing-event 事件
window.addEventListener('single-spa:before-routing-event', ({detail: {oldUrl, newUrl, cancelNavigation}}) => {if (new URL(oldUrl).pathname === '/route1' && new URL(newUrl).pathname === '/route2') {cancelNavigation();}
})

Custom Events

每当重新路由时,single-spa都会触发一系列自定义事件。每当浏览器URL发生任何更改或调用triggerAppChange时,都会发生重新路由

window.addEventListener('single-spa:before-routing-event', evt => {const { originalEvent, newAppStatuses, appsByNewStatus, totalAppChanges, oldUrl, newUrl, navigationIsCanceled, cancelNavigation } = evt.detail;console.log('original event that triggered this single-spa event', originalEvent); // PopStateEvent | HashChangeEvent | undefinedconsole.log('the new status for all applications after the reroute finishes', newAppStatuses) // { app1: MOUNTED, app2: NOT_MOUNTED }console.log('the applications that changed, grouped by their status', appsByNewStatus) // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }console.log('number of applications that changed status so far during this reroute', totalAppChanges); // 2console.log('the URL before the navigationEvent', oldUrl); // http://localhost:8080/old-routeconsole.log('the URL after the navigationEvent', newUrl); // http://localhost:8080/new-routeconsole.log('has the navigation been canceled', navigationIsCanceled); // false// The cancelNavigation function is only defined in the before-routing-eventevt.detail.cancelNavigation();
})

before-app-change event

当至少一个应用程序更改状态,在重新路由之前会触发 single-spa:before-app-change事件。

window.addEventListener('single-spa:before-app-change', (evt) => {console.log('single-spa is about to mount/unmount applications!');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { app1: MOUNTED }console.log(evt.detail.appsByNewStatus) // { MOUNTED: ['app1'], NOT_MOUNTED: [] }console.log(evt.detail.totalAppChanges) // 1
});

before-no-app-change

当零个应用程序更改状态,在重新路由之前会触发 single-spa:before-no-app-change事件。

window.addEventListener('single-spa:before-no-app-change', (evt) => {console.log('single-spa is about to do a no-op reroute');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { }console.log(evt.detail.appsByNewStatus) // { MOUNTED: [], NOT_MOUNTED: [] }console.log(evt.detail.totalAppChanges) // 0
});

before-routing-event

在每个路由事件发生之前(即在每个hashchange,popstate或triggerAppChange之后)都会触发 single-spa:before-routing-event 事件,即使不需要更改已注册的应用程序也是如此。

window.addEventListener('single-spa:before-routing-event', (evt) => {console.log('single-spa is about to mount/unmount applications!');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { }console.log(evt.detail.appsByNewStatus) // { MOUNTED: [], NOT_MOUNTED: [] }console.log(evt.detail.totalAppChanges) // 0
});

before-mount-routing-event

在 routing-event 之前,在 before-routing-event 之后,保证在所有应用 unmounted 之后,所有新应用 mounted 之前触发

window.addEventListener('single-spa:before-mount-routing-event', (evt) => {console.log('single-spa is about to mount/unmount applications!');console.log(evt.detail)console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { app1: MOUNTED }console.log(evt.detail.appsByNewStatus) // { MOUNTED: ['app1'], NOT_MOUNTED: [] }console.log(evt.detail.totalAppChanges) // 1
});

before-first-mount

在任何一个应用第一次挂载之前触发,因此只触发一次,这在应用已经加载好但是还没 mounting 之后。

window.addEventListener('single-spa:before-first-mount', () => {console.log('single-spa is about to mount the very first application for the first time');
});

first-mount

在任何一个应用第一次挂载之前触发,因此只触发一次

window.addEventListener('single-spa:first-mount', () => {console.log('single-spa just mounted the very first application');
});

app-change event

至少一个应用 loaded、bootstrap、mounted、unmounted 或者 unloaded 触发,hashchange,popstate 或triggerAppChange不会导致触发事件。

window.addEventListener('single-spa:app-change', (evt) => {console.log('A routing event occurred where at least one application was mounted/unmounted');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { app1: MOUNTED, app2: NOT_MOUNTED }console.log(evt.detail.appsByNewStatus) // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }console.log(evt.detail.totalAppChanges) // 2
});

no-app-change event

当没有应用 loaded、boostrapped 、mounted、unmounted 或者 unloaded 时触发。每个路由事件只会触发一个。

window.addEventListener('single-spa:no-app-change', (evt) => {console.log('A routing event occurred where zero applications were mounted/unmounted');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { }console.log(evt.detail.appsByNewStatus) // { MOUNTED: [], NOT_MOUNTED: [] }console.log(evt.detail.totalAppChanges) // 0
});

routing-event

每次发生路由事件时(在每个hashchange,popstate或triggerAppChange之后),都​​会触发 single-spa:routing-event事件,即使无需更改已注册的应用程序;之后 single-spa 会验证所有应用正确 loaded、bootstrapped、mounted、unmounted

window.addEventListener('single-spa:routing-event', (evt) => {console.log('single-spa finished mounting/unmounting applications!');console.log(evt.detail.originalEvent) // PopStateEventconsole.log(evt.detail.newAppStatuses) // { app1: MOUNTED, app2: NOT_MOUNTED }console.log(evt.detail.appsByNewStatus) // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }console.log(evt.detail.totalAppChanges) // 2
});

微前端 Micro-Frontnds - Single-SPA Application API相关推荐

  1. 微前端(Micro Frontend ) 落地实施的一些具体例子

    前文微前端概述(Micro Frontends) 以及相比单体应用,微前端能带来什么好处 简单介绍了微前端的概念,本文来看一个具体的应用例子. 原文地址 想象一个网站,客户可以在其中订购外卖食品.从表 ...

  2. 【微前端架构】微前端——功能团队中缺失的一块拼图

    在任何合法的前端开发团队中,提高可扩展性和敏捷性很少会成为头等大事.在处理大型.复杂的产品时,如何确保快速.频繁地交付同时包含后端和前端的功能?像后端那样将前端单体分解成许多更小的部分似乎是答案.如果 ...

  3. 关于前端开发 Framework Agnostic 和微前端的话题

    1 What does it mean by Framework agnostic? 框架不可知一般意味着确切地说,即不可知或独立于任何框架. 举个例子,公司或产品团队经常处理以下优先事项: 通常在大 ...

  4. 微前端调研及简析SPA实现原理

    最近对微前端讨论很多,梳理下自己对微前端的理解以及业内的一些微前端尝试反馈. 第零部分:自己对微前端理解 第一部分:基于Single-SPA微前端的一些demo 第二部分:Single-SPA微前端实 ...

  5. 微前端概述(Micro Frontends) 以及相比单体应用,微前端能带来什么好处

    原文地址 好的前端开发很难. 扩展前端开发,让多个团队可以同时开发一个大型复杂的产品就更难了.在本文中,我们将描述将前端单体分解成许多更小.更易于管理的部分的最新趋势,以及这种架构如何提高处理前端代码 ...

  6. 微前端架构在容器平台的应用

    源宝导读:随着业务的发展,天际-星舟平台未来需要解决与其他云共创共建,跨团队高效协作等诸多问题,而星舟现有的技术架构将难以支撑.本文将介绍星舟平台如何通过向更先进的"微前端"架构演 ...

  7. Bifrost微前端框架及其在美团闪购中的实践

    Bifrost(英 ['bi:frɔst])原意彩虹桥,北欧神话中是连通天地的一条通道.而在漫威电影<雷神>中,Bifrost是神域--阿斯加德(Asgard)的出入口,神域的人通过它自由 ...

  8. 闲庭信步聊前端 - 见微知著微前端

    笔者初次接触微前端在2020年7月,是从同事的口中听说的.虽然不算是一个早期接触者,但是也确实的推动和跟进了内部某大型项目的开发和落地.也希望能把一些走过的坑和一些思考分享给大家.文内所指应用均为PC ...

  9. 微前端——single-spa源码学习

    前言 本来是想直接去学习下qiankun的源码,但是qiankun是基于single-spa做的二次封装,通过解决了single-spa的一些弊端和不足来帮助大家能更简单.无痛的构建一个生产可用微前端 ...

  10. 微前端在平台级管理系统中的最佳实践

    微前端在平台级管理系统中的最佳实践 一.什么是微前端 二.什么是通用管理端工程 三.当管理端工程遇上微前端 四.未来展望 作者:杨朋飞 一.什么是微前端 近十年来,前端技术有了长足发展,各种概念与框架 ...

最新文章

  1. Linux的scp命令
  2. linux pppd源码下载_pppd源代码分析
  3. OpenCASCADE绘制测试线束:几何命令之预测
  4. verilog 除法器
  5. UVa 988 - Many Paths, One Destination
  6. html5 心,HTML5你必须知道的28个新特性
  7. NMS 原理和c++实现,已测试通过
  8. paip . 解决spring No unique bean of type [com.mijie.homi.search.service.index.MoodUserIndexService]
  9. C# WPF中DataGrid的数据绑定(Binding)
  10. 当前只读状态:是_DM数据库的启停以及数据库状态检查
  11. 【预测模型】基于VMD结合Elman神经网络预测数据matlab代码
  12. Delphi第三方控件大比拼
  13. java 时区处理_JAVA时区处理(转)
  14. 火线——地线——零线
  15. 一些dalao的模板
  16. 对自己狠一点-----胡言乱语
  17. 来吧,一文彻底搞懂Java中最特殊的存在——null
  18. 智能交通工程质量的第三方监测
  19. 我 stormzhang 来报道了!
  20. n个数字生成排列组合对象的算法(Johnson-Trotter)

热门文章

  1. php扩展引擎手册,模板引擎-THINKPHP 5.0 手册最新版
  2. ASP.NET ZERO 学习 —— (4) 开发手册之AccountController
  3. 科技论文之Introduction部分写作
  4. 利用文本挖掘技术来找出《天龙八部》中的“小鲜词”
  5. 火狐受信任站点设置_火狐浏览器如何添加信任站点?添加信任站点的方法说明...
  6. Oracle查询语句中SYSDATE与HIRE_DATE的区分
  7. 光谱辐射计算(MATLAB)
  8. 游戏运行库microsoft visual c++ 2010 spi 64检测不到
  9. C语言if语句中常见的问题
  10. 硬核!自动驾驶如何做数据标注?特斯拉EP3 Auto Labeling深度分析