@hsui/micro-app
Version:
Hundsun micro-app framework
105 lines (103 loc) • 4.12 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
var _excluded = ["logger"];
import { importEntry } from 'import-html-entry';
import { getAppStatus, getMountedApps, NOT_LOADED } from 'single-spa';
import { frameworkConfiguration } from './config';
// RIC and shim for browsers setTimeout() without it
var requestIdleCallback = window.requestIdleCallback || function requestIdleCallback(cb) {
var start = Date.now();
return setTimeout(function () {
cb({
didTimeout: false,
timeRemaining: function timeRemaining() {
return Math.max(0, 50 - (Date.now() - start));
}
});
}, 1);
};
var isSlowNetwork = navigator.connection ? navigator.connection.saveData || navigator.connection.type !== 'wifi' && navigator.connection.type !== 'ethernet' && /(2|3)g/.test(navigator.connection.effectiveType) : false;
/**
* prefetch assets, do nothing while in mobile network
* @param entry
* @param opts
*/
function prefetch(entry, opts) {
if (!navigator.onLine || isSlowNetwork) {
// Don't prefetch if in a slow network or offline
return;
}
requestIdleCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
var _yield$importEntry, getExternalScripts, getExternalStyleSheets;
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return importEntry(entry, opts);
case 2:
_yield$importEntry = _context.sent;
getExternalScripts = _yield$importEntry.getExternalScripts;
getExternalStyleSheets = _yield$importEntry.getExternalStyleSheets;
requestIdleCallback(getExternalStyleSheets);
requestIdleCallback(getExternalScripts);
case 7:
case "end":
return _context.stop();
}
}, _callee);
})));
}
function prefetchAfterFirstMounted(apps, opts) {
window.addEventListener('single-spa:first-mount', function listener() {
var notLoadedApps = apps.filter(function (app) {
return getAppStatus(app.name) === NOT_LOADED;
});
if (process.env.NODE_ENV === 'development') {
var mountedApps = getMountedApps();
frameworkConfiguration.logger.debug("prefetch starting after ".concat(mountedApps, " mounted..."), notLoadedApps);
}
notLoadedApps.forEach(function (_ref2) {
var entry = _ref2.entry;
return prefetch(entry, opts);
});
window.removeEventListener('single-spa:first-mount', listener);
});
}
export function prefetchImmediately(apps) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var logger = opts.logger,
commonOpts = _objectWithoutProperties(opts, _excluded);
if (process.env.NODE_ENV === 'development') {
logger && (frameworkConfiguration.logger = logger);
frameworkConfiguration.logger.debug('微前端框架执行应用预加载', apps);
}
apps.forEach(function (_ref3) {
var entry = _ref3.entry;
return prefetch(entry, commonOpts);
});
}
export function doPrefetchStrategy(apps, prefetchStrategy, importEntryOpts) {
var appsName2Apps = function appsName2Apps(names) {
return apps.filter(function (app) {
return names.includes(app.name);
});
};
if (Array.isArray(prefetchStrategy)) {
// 第一个微应用 mounted 后开始加载数组内的微应用资源
prefetchAfterFirstMounted(appsName2Apps(prefetchStrategy), importEntryOpts);
} else {
switch (prefetchStrategy) {
case true:
// 第一个微应用 mount 完成后开始预加载其他微应用的静态资源
prefetchAfterFirstMounted(apps, importEntryOpts);
break;
case 'all':
// 主应用 start 后即开始预加载所有微应用静态资源
prefetchImmediately(apps, importEntryOpts);
break;
default:
break;
}
}
}