single-spa源码分析之按需加载
源码相关
与 activeWhen 相关
activeWhen API 可以控制页面是否需要加载
以下片段是源码及注释
// \single-spa-source-code\src\applications :447
/*** 得到一个函数,函数负责判断浏览器当前地址是否和用户给定的baseURL相匹配,匹配返回true,否则返回false*/
function sanitizeActiveWhen(activeWhen) {// activeWhen 接收一个函数(箭头函数),将location传入 (location) => location.hash.startsWith('#/app1'); 调用后返回一个字符串// location.hash:hash属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)// startsWith() 方法用于检测字符串是否以指定的前缀开始let activeWhenArray = Array.isArray(activeWhen) ? activeWhen : [activeWhen];// 保证数组中每个元素都是一个函数activeWhenArray = activeWhenArray.map((activeWhenOrPath) =>typeof activeWhenOrPath === "function"? activeWhenOrPath: // activeWhen如果是一个路径,则保证成一个函数pathToActiveWhen(activeWhenOrPath));// 返回一个函数,函数返回一个 boolean 值return (location) =>activeWhenArray.some((activeWhen) => activeWhen(location)); // 调用用户配置的函数,传入location
}// activeWhen传入的不是函数,而是字符串或者数组,则特殊处理
// '/app1', '/users/:userId/profile', '/pathname/#/hash' ['/pathname/#/hash', '/app1']
// 具体见官方文档api,有详细说明:https://zh-hans.single-spa.js.org/docs/api
export function pathToActiveWhen(path, exactMatch) {// 根据用户提供的baseURL,生成正则表达式const regex = toDynamicPathValidatorRegex(path, exactMatch);// 函数返回boolean值,判断当前路由是否匹配用户给定的路径return (location) => {// compatible with IE10let origin = location.origin;if (!origin) {origin = `${location.protocol}//${location.host}`;}const route = location.href.replace(origin, "").replace(location.search, "").split("?")[0];return regex.test(route);};
}
sanitizeActiveWhen
与pathToActiveWhen
是两个关键方法,控制是否需要按需加载 app.js,像我目前项目中写的一般都是(location) => true
,也就是默认加载所有 app.js,优化点在于activeWhen
函数,能够实现按需加载(根据路径加载)。
single-spa
提供了两种挂载方式,分为简单参数和对象参数。(具体见官方文档 api,有详细说明:https://zh-hans.single-spa.js.org/docs/api)
简单参数
singleSpa.registerApplication("appName",() => System.import("appName"),(location) => location.pathname.startsWith("appName")
);
对象参数
singleSpa.registerApplication({name: 'appName',app: () => System.import('appName'),activeWhen: '/appName'customProps: {}
})
二者区别在于如果选择对象参数时,需要走一层转换pathToActiveWhen
函数,另外activeWhen
属性也可以传递数组,一个数组中任何条件为真,则保留应用活动。如activeWhen:['/authority', '/test']
,访问例如http://localhost:7000/test
,http://localhost:7000/test
,都能激活应用。作者在源码中也有相应的逻辑,let activeWhenArray = Array.isArray(activeWhen) ? activeWhen : [activeWhen];
https://zh-hans.single-spa.js.org/docs/api/#pathtoactivewhen,文档中详细介绍了pathToActiveWhen
的例子。
single-spa
规定我们使用按需时传入的格式,具体根据项目情况而定
如采用 Hash 模式:
(location) => location.hash.startsWith("#/app1");
如采用 history 模式:
(location) => location.pathname.startsWith("app1");
若是当前浏览器 URL 与#/app1
相匹配时(假定使用的是 hash),
single-spa 调用sanitizeActiveWhen
方法时,接收activeWhen
参数,在\single-spa-source-code\src\applications :434 做了一层校验validateRegisterWithConfig(appNameOrConfig);
,注意看validateRegisterWithConfig
函数,其中allowsStringAndFunction
箭头函数,规范和保证了activeWhen
必须是字符串,或者函数或者数组。
export function validateRegisterWithConfig(config) {// 1. 异常判断,应用的配置对象不能是数组或者nullif (Array.isArray(config) || config === null)throw Error(formatErrorMessage(39,__DEV__ && "Configuration object can't be an Array or null!"));// 2. 应用配置必须是指定的几个关键字const validKeys = ["name", "app", "activeWhen", "customProps"];// 过滤函数,将不是 validKeys 中的key,过滤出来。const invalidKeys = Object.keys(config).reduce((invalidKeys, prop) =>validKeys.indexOf(prop) >= 0 ? invalidKeys : invalidKeys.concat(prop),[]);// 如果存在无效的key,则抛出一个错误,表示书写不合法if (invalidKeys.length !== 0)throw Error(formatErrorMessage(38,__DEV__ &&// 配置对象只接受 validKeys 中的属性,其他的无效`The configuration object accepts only: ${validKeys.join(", ")}. Invalid keys: ${invalidKeys.join(", ")}.`,validKeys.join(", "),invalidKeys.join(", ")));// 3. 应用名称存在校验if (typeof config.name !== "string" || config.name.length === 0)throw Error(formatErrorMessage(20,__DEV__ &&// 应用名称必须存在,且不能是空字符串"The config.name on registerApplication must be a non-empty string"));// app 属性只能是一个对象或者函数// 对象是一个已被解析过的对象,是一个包含各个生命周期的对象;// 加载函数必须返回一个 promise// 以上信息在官方文档中有提到:https://zh-hans.single-spa.js.org/docs/configurationif (typeof config.app !== "object" && typeof config.app !== "function")throw Error(formatErrorMessage(20,__DEV__ &&"The config.app on registerApplication must be an application or a loading function"));// 第三个参数,可以是一个字符串,也可以是一个函数,也可以是两者组成的一个数组,表示当前应该被激活的应用的baseURLconst allowsStringAndFunction = (activeWhen) =>typeof activeWhen === "string" || typeof activeWhen === "function";if (!allowsStringAndFunction(config.activeWhen) &&!(Array.isArray(config.activeWhen) &&config.activeWhen.every(allowsStringAndFunction)))throw Error(formatErrorMessage(24,__DEV__ &&// activeWhen 必须是字符串,或者函数或者数组"The config.activeWhen on registerApplication must be a string, function or an array with both"));// 5. 自定义属性校验, 必须是一个对象if (!validCustomProps(config.customProps))throw Error(formatErrorMessage(22,// customProps 必须是对象,不能是函数或者数组,也不能为空__DEV__ && "The optional config.customProps must be an object"));
}
single-spa源码分析之按需加载相关推荐
- Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean())
"属性填充",也是在populateBean()方法中. 首先回顾下CreateBean的主流程: 如果是单例模式,从factoryBeanInstanceCache 缓存中获取B ...
- Spring Ioc源码分析 之 Bean的加载(4):实例化Bean(createBeanInstance()方法)
实例化 Bean 在doCreateBean()代码 <2> 处,有一行代码instanceWrapper = createBeanInstance(beanName, mbd, args ...
- Myabtis源码分析五-Mybatis配置加载完全图解,建造者模式的使用,涵盖Java各种技术栈
private SqlSessionFactory sqlSessionFactory; @Before public void init() throws IOException { //----- ...
- nhibernate源码分析之六: Criteria数据加载
ICriteria是使用Expression进行数据加载的接口, 提供了设置表达式(Expression), 排序方式(Order), 分页记录等操作. 它使用一种类似于SQL语句where表达表的方 ...
- Spring Ioc源码分析 之 Bean的加载(7):初始化
接着分析doCreateBean()的第6步--初始化 bean 实例对象 首先回顾下CreateBean的主流程: 如果是单例模式,从factoryBeanInstanceCache 缓存中获取Be ...
- Spring Ioc源码分析 之 Bean的加载(5):循环依赖处理(populateBean())
首先回顾下Bean加载的主流程: 1.如果是单例模式,从factoryBeanInstanceCache 缓存中获取BeanWrapper 实例对象并删除缓存 2.调用 createBeanInsta ...
- MPF源码分析之资源文件加载
本文将分析MPF客户端框架中资源文件相关的源代码,以github包中提供的qq界面demo作为 起点,一步一步分析程序的运行原理: 主程序很简单,代码如下: int APIENTRY _tWinMai ...
- Angular (SPA) WebPack模块化打包、按需加载解决方案完整实现
Angular (SPA) WebPack模块化打包.按需加载解决方案完整实现 参考文章: (1)Angular (SPA) WebPack模块化打包.按需加载解决方案完整实现 (2)https:// ...
- 直播app系统源码通过CSS液体实现加载动画
直播app系统源码通过CSS液体实现加载动画 首先我们要让元素能够旋转起来,可以使用transform中的rotate进行2D的360deg旋转. 紧接着我们可以通过CSS变量(–开头的形式)结合an ...
- 框架源码专题:springIOC的加载过程,bean的生命周期,结合spring源码分析
文章目录 1.BeanFactory和ApplicationContext的区别? 2. IOC与 Bean的加载过程 ①:初始化容器DefaultListableBeanFactory ②:创建读取 ...
最新文章
- eureka需要替换吗_iOS第三方库Eureka实现定制动画详解(二):万变不离其宗-Row组件...
- Myeclipse优化配置
- Python从菜鸟到高手(4):导入Python模块
- Kettle使用_12 CSV文件仅并发运行与复制数量
- java冻结行列,poi冻结行和列 - osc_0k23td2u的个人空间 - OSCHINA - 中文开源技术交流社区...
- nano-pc-t1 4412 显示驱动分析
- ajax juey,锋利的qjuey-ajax
- python快速入门步骤_Python快速入门
- 【Flink-未解决】 FLink TaskManager with id is no longer reachable
- 一张图读懂nginx多线程高并发
- spanT之高性能字符串操作实测
- [转载] 五、字符串类的实现及子串查找算法
- 怎样输出矩阵乘积C语言,c语言矩阵相乘
- jquery-animate()动画
- Qt安卓开发环境搭建
- 支付宝APP支付功能开发
- qq相册回收站复原显示服务器繁忙,qq回收站照片怎么找回?3大恢复方法3分钟解决...
- 【LaTeX】下载及安装步骤
- vs2013 格式化代码 快捷键
- Mybatis中取循环获取 Oracle自增序列 重复值问题
热门文章
- linux:修改grub文件实现双系统默认进入windows系统
- Charles(或fiddler)抓Android应用包,CA证书安装及代理后APP无法连接上网的解决办法,亲测!
- 基于推荐算法的在线交友系统计算机毕设
- 十二生肖APP系统开发源码介绍
- .net6中的?问号和叹号用处
- 【linux】E45: ‘readonly‘ option is set (add ! to override)
- 【HTML——旋转火焰】(效果+代码)
- 贪吃蛇c++实现 实训认识小游戏
- python设置字体输出颜色等效果
- 亩产532.6公斤!国稻种芯潍坊粮农产业园功能旱稻山东首次测产