源码分析
思维导图
Preview
具体过程
Single-Spa
是一个子应用加载器 + 状态机的结合体, 同时维护了各个子应用的状态, 以及在适当的时候负责更改子应用的状态,执行相应的生命周期函数。
一、registerApplication 注册子应用
single-spa/src/applications/apps.js
/**
* 注册应用,两种方式
* registerApplication('app1', loadApp(url), activeWhen('/app1'), customProps)
* registerApplication({
* name: 'app1',
* app: loadApp(url),
* activeWhen: activeWhen('/app1'),
* customProps: {}
* })
* @param {*} appNameOrConfig 应用名称或者应用配置对象
* @param {*} appOrLoadApp 应用的加载方法,是一个 promise
* @param {*} activeWhen 判断应用是否激活的一个方法,方法返回 true or false
* @param {*} customProps 传递给子应用的 props 对象
*/
export function registerApplication(
appNameOrConfig,
appOrLoadApp,
activeWhen,
customProps
) {
/**
* 格式化用户传递的应用配置参数
* registration = {
* name: 'app1',
* loadApp: 返回promise的函数,
* activeWhen: 返回boolean值的函数,
* customProps: {},
* }
*/
const registration = sanitizeArguments(
appNameOrConfig,
appOrLoadApp,
activeWhen,
customProps
);
// 判断应用是否重名
if (getAppNames().indexOf(registration.name) !== -1)
throw Error(
formatErrorMessage(
21,
__DEV__ &&
`There is already an app registered with name ${registration.name}`,
registration.name
)
);
// 将各个应用的配置信息都存放到 apps 数组中
apps.push(
// 给每个应用增加一个内置属性
assign(
{
loadErrorTime: null,
// 最重要的,应用的状态
status: NOT_LOADED,
parcels: {},
devtools: {
overlays: {
options: {},
selectors: [],
},
},
},
registration
)
);
// 浏览器环境运行
if (isInBrowser) {
// https://zh-hans.single-spa.js.org/docs/api#ensurejquerysupport
// 如果页面中使用了jQuery,则给jQuery打patch
ensureJQuerySupport();
reroute();
}
}
二、sanitizeArguments 格式化用户传递的子应用配置参数
single-spa/src/applications/apps.js
// 返回处理后的应用配置对象
function sanitizeArguments(
appNameOrConfig,
appOrLoadApp,
activeWhen,
customProps
) {
// 判断第一个参数是否为对象
const usingObjectAPI = typeof appNameOrConfig === "object";
// 初始化应用配置对象
const registration = {
name: null,
loadApp: null,
activeWhen: null,
customProps: null,
};
if (usingObjectAPI) {
// 注册应用的时候传递的参数是对象
validateRegisterWithConfig(appNameOrConfig);
registration.name = appNameOrConfig.name;
registration.loadApp = appNameOrConfig.app;
registration.activeWhen = appNameOrConfig.activeWhen;
registration.customProps = appNameOrConfig.customProps;
} else {
// 参数列表
validateRegisterWithArguments(
appNameOrConfig,
appOrLoadApp,
activeWhen,
customProps
);
registration.name = appNameOrConfig;
registration.loadApp = appOrLoadApp;
registration.activeWhen = activeWhen;
registration.customProps = customProps;
}
// 如果第二个参数不是一个函数,比如是一个包含已经生命周期的对象,则包装成一个返回 promise 的函数
registration.loadApp = sanitizeLoadApp(registration.loadApp);
// 如果用户没有提供 props 对象,则给一个默认的空对象
registration.customProps = sanitizeCustomProps(registration.customProps);
// 保证activeWhen是一个返回boolean值的函数
registration.activeWhen = sanitizeActiveWhen(registration.activeWhen);
// 返回处理后的应用配置对象
return registration;
}