🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@ttk/micro-frontend-react

Package Overview
Dependencies
Maintainers
5
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ttk/micro-frontend-react - npm Package Compare versions

Comparing version
0.0.3
to
0.0.4
+322
-218
dist/index.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('qiankun'), require('react-dom')) :
typeof define === 'function' && define.amd ? define(['exports', 'react', 'qiankun', 'react-dom'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ttk_mf_react = {}, global.react, global.qiankun, global.ReactDOM));
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('qiankun'), require('react-dom')) :
typeof define === 'function' && define.amd ? define(['exports', 'react', 'qiankun', 'react-dom'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ttk_mf_react = {}, global.react, global.qiankun, global.ReactDOM));
}(this, (function (exports, React, qiankun, ReactDOM) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
var STYLE_APP = {
width: '100%',
height: '100%',
overflow: 'hidden'
};
var STYLE_APP_CONTAINER = {
width: '100%',
height: '100%'
};
var STYLE_APP_SPIN = {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
};
var STYLE_APP_ERROR = {
width: '100%',
height: '100%',
padding: 10,
color: 'red'
};
var STYLE_APP_ERROR_MSG = {
display: 'block',
fontSize: 16
};
function mfApp(props) {
var mfAppConfig = props.mfAppConfig;
var name = mfAppConfig.name,
entry = mfAppConfig.entry,
startAppName = mfAppConfig.startAppName,
_mfAppConfig$delayLoa = mfAppConfig.delayLoading,
delayLoading = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
params = mfAppConfig.params,
callbacks = mfAppConfig.callbacks,
onSaveState = mfAppConfig.onSaveState,
restoreState = mfAppConfig.restoreState,
_mfAppConfig$singular = mfAppConfig.singular,
singular = _mfAppConfig$singular === void 0 ? true : _mfAppConfig$singular,
RenderLoading = mfAppConfig.renderLoading,
RenderError = mfAppConfig.renderError;
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var _useState = React.useState(true),
loading = _useState[0],
setLoading = _useState[1];
function createCommonjsModule(fn, basedir, module) {
return module = {
path: basedir,
exports: {},
require: function (path, base) {
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
}
}, fn(module, module.exports), module.exports;
}
var _useState2 = React.useState(false),
error = _useState2[0],
setError = _useState2[1];
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}
var _useState3 = React.useState("\u5FAE\u5E94\u7528" + name + "\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\uFF01"),
errorMsg = _useState3[0];
var _extends_1 = createCommonjsModule(function (module) {
function _extends() {
module.exports = _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
var _useState4 = React.useState(''),
errorDesc = _useState4[0],
setErrorDesc = _useState4[1];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
var appRef = React.useRef(null);
var ref = React.useRef(null);
var errorHandler = React.useCallback(function (event) {
setLoading(false);
setError(true);
setErrorDesc(event.reason ? event.reason.stack : event.type);
}, []);
React.useEffect(function () {
if (!name || !entry) {
var description = "" + (!name ? 'MicroApp的name不能为空,微应用的名称,微应用之间必须确保唯一。' : '') + (!entry ? 'entry不能为空,微应用的入口。' : '');
setLoading(false);
setError(true);
setErrorDesc(description);
}
return target;
};
if (delayLoading) {
return;
}
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _extends.apply(this, arguments);
}
qiankun.addGlobalUncaughtErrorHandler(errorHandler);
var configuration = {
sandbox: {
experimentalStyleIsolation: true
},
singular: singular
};
module.exports = _extends;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
if (!appRef.current) {
appRef.current = qiankun.loadMicroApp({
name: name,
entry: entry,
container: ref.current || '',
props: {
restoreState: restoreState,
onSaveState: onSaveState,
startAppName: startAppName,
params: params,
callbacks: callbacks
}
}, configuration);
appRef.current.mountPromise.then(function () {
setLoading(false);
});
} else if (appRef.current.update) {
appRef.current.update({
container: ref.current,
restoreState: restoreState,
onSaveState: onSaveState,
startAppName: startAppName,
params: params,
callbacks: callbacks
});
}
var _extends = /*@__PURE__*/getDefaultExportFromCjs(_extends_1);
return function () {
var _appRef$current;
var STYLE_APP = {
width: '100%',
height: '100%',
overflow: 'hidden'
};
var STYLE_APP_CONTAINER = {
width: '100%',
height: '100%'
};
var STYLE_APP_SPIN = {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
};
var STYLE_APP_ERROR = {
width: '100%',
height: '100%',
padding: 10,
color: 'red'
};
var STYLE_APP_ERROR_MSG = {
display: 'block',
fontSize: 16
};
function MfApp(props) {
var mfAppConfig = props.mfAppConfig;
var name = mfAppConfig.name,
entry = mfAppConfig.entry,
startAppName = mfAppConfig.startAppName,
_mfAppConfig$delayLoa = mfAppConfig.delayLoad,
delayLoad = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
params = mfAppConfig.params,
callbacks = mfAppConfig.callbacks,
onSaveState = mfAppConfig.onSaveState,
restoreState = mfAppConfig.restoreState,
singular = mfAppConfig.singular,
RenderLoading = mfAppConfig.renderLoading,
RenderError = mfAppConfig.renderError;
console.log('mount startAppName', startAppName);
var status = (_appRef$current = appRef.current) == null ? void 0 : _appRef$current.getStatus();
var _useState = React.useState(true),
loading = _useState[0],
setLoading = _useState[1];
if ('MOUNTED' === status) {
var _appRef$current2;
var _useState2 = React.useState(false),
error = _useState2[0],
setError = _useState2[1];
(_appRef$current2 = appRef.current) == null ? void 0 : _appRef$current2.unmount();
}
var _useState3 = React.useState("\u5FAE\u5E94\u7528" + name + "\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\uFF01"),
errorMsg = _useState3[0];
qiankun.removeGlobalUncaughtErrorHandler(errorHandler);
};
}, [mfAppConfig, delayLoading]);
return /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP
}, (delayLoading || loading) && RenderLoading ? /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_SPIN
}, /*#__PURE__*/React__default['default'].createElement(RenderLoading, {
loading: loading
})) : null, error ? /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_ERROR
}, RenderError ? /*#__PURE__*/React__default['default'].createElement(RenderError, {
message: errorMsg,
description: errorDesc
}) : [/*#__PURE__*/React__default['default'].createElement("span", {
style: STYLE_APP_ERROR_MSG
}, errorMsg), /*#__PURE__*/React__default['default'].createElement("span", null, errorDesc)]) : null, /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_CONTAINER,
ref: ref
}));
}
var _useState4 = React.useState(''),
errorDesc = _useState4[0],
setErrorDesc = _useState4[1];
/**
* single-SPA生命周期钩子,只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
var bootstrap = function bootstrap(props) {
var packageName = props.packageName,
startAppName = props.startAppName;
console.log("[" + packageName + "] app bootstraped. startAppName:", startAppName);
};
/**
* single-SPA生命周期钩子,应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
var appRef = React.useRef(null);
var ref = React.useRef(null);
var errorHandler = React.useCallback(function (event) {
setLoading(false);
setError(true);
setErrorDesc(event.reason ? event.reason.stack : event.type);
}, []);
React.useEffect(function () {
if (!name || !entry) {
var description = "" + (!name ? 'MicroApp的name不能为空,微应用的名称,微应用之间必须确保唯一。' : '') + (!entry ? 'entry不能为空,微应用的入口。' : '');
setLoading(false);
setError(true);
setErrorDesc(description);
}
var mount = function mount(props) {
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
restoreState = props.restoreState,
params = props.params,
callbacks = props.callbacks,
Root = props.render;
console.log("[" + packageName + "] app mounted. startAppName:", startAppName);
ReactDOM__default['default'].render( /*#__PURE__*/React__default['default'].createElement(Root, {
startAppName: startAppName,
initData: restoreState,
params: params,
callbacks: callbacks
}), container ? container.querySelector("#" + targetDomId) : document.getElementById(targetDomId));
};
/**
* single-SPA生命周期钩子,应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
if (delayLoad) {
return;
}
var unmount = function unmount(props) {
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
onSaveState = props.onSaveState,
state = props.state;
console.log("[" + packageName + "] app unmount. startAppName:", startAppName);
qiankun.addGlobalUncaughtErrorHandler(errorHandler);
var configuration = {
sandbox: {
experimentalStyleIsolation: true
},
singular: singular
};
if (startAppName && state && onSaveState) {
state.get(startAppName).filter(function (value, key) {
return key.startsWith('AppLoader');
}).take(1).forEach(function (value) {
onSaveState(value.get('data').toJS());
});
}
if (!appRef.current) {
appRef.current = qiankun.loadMicroApp({
name: name,
entry: entry,
container: ref.current || '',
props: {
restoreState: restoreState,
onSaveState: onSaveState,
startAppName: startAppName,
params: params,
callbacks: callbacks
}
}, configuration);
appRef.current.mountPromise.then(function () {
setLoading(false);
});
} else if (appRef.current.update) {
appRef.current.update({
container: ref.current,
restoreState: restoreState,
onSaveState: onSaveState,
startAppName: startAppName,
params: params,
callbacks: callbacks
});
}
var element = container ? container.querySelector("#" + targetDomId) : document.getElementById(targetDomId);
element && ReactDOM__default['default'].unmountComponentAtNode(element);
};
/**
* single-SPA可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
return function () {
var _appRef$current;
var update = function update(props) {
var _container$firstEleme;
console.log('unmount startAppName', startAppName);
(_appRef$current = appRef.current) == null ? void 0 : _appRef$current.safeUnmount();
qiankun.removeGlobalUncaughtErrorHandler(errorHandler);
};
}, [mfAppConfig, delayLoad]);
return /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP
}, (delayLoad || loading) && RenderLoading ? /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_SPIN
}, /*#__PURE__*/React__default['default'].createElement(RenderLoading, {
loading: loading
})) : null, error ? /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_ERROR
}, RenderError ? /*#__PURE__*/React__default['default'].createElement(RenderError, {
message: errorMsg,
description: errorDesc
}) : [/*#__PURE__*/React__default['default'].createElement("span", {
style: STYLE_APP_ERROR_MSG
}, errorMsg), /*#__PURE__*/React__default['default'].createElement("span", null, errorDesc)]) : null, /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_CONTAINER,
ref: ref
}));
} // 初始化 state
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
restoreState = props.restoreState,
params = props.params,
callbacks = props.callbacks,
Update = props.render;
console.log("[" + packageName + "] app update. startAppName:", startAppName);
var element = (container == null ? void 0 : (_container$firstEleme = container.firstElementChild) == null ? void 0 : _container$firstEleme.querySelector("#" + targetDomId)) || document.getElementById(targetDomId);
ReactDOM__default['default'].render( /*#__PURE__*/React__default['default'].createElement(Update, {
startAppName: startAppName,
initData: restoreState,
params: params,
callbacks: callbacks
}), element);
};
var actions = qiankun.initGlobalState({
// 所有app资源加载状态
hasAppLoading: false,
// 第一个app挂载完成状态
firstMounted: false
});
/**
* 单实例场景,单实例指的是同一时间只会渲染一个微应用
var lifecycle = /*#__PURE__*/Object.freeze({
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
});
*/
exports.lifecycle = lifecycle;
exports.mfApp = mfApp;
function SingularMfApp(props) {
// 当前app加载状态
var _useState5 = React.useState(true),
delayLoad = _useState5[0],
setDelayLoad = _useState5[1];
Object.defineProperty(exports, '__esModule', { value: true });
React.useEffect(function () {
// 第二个参数为true时,调用该函数就马上执行回调,此时state === prev,可进行初始化。
actions.onGlobalStateChange(function (state, prev) {
if (state === prev) {
// 初始化
if (!state.firstMounted) {
// 第一个app未挂载,则监听微应用生命周期
qiankun.runAfterFirstMounted(function () {
actions.setGlobalState({
hasAppLoading: false,
firstMounted: true
});
}); // 无app在加载,当前app进入加载状态
if (!state.hasAppLoading) {
actions.setGlobalState({
hasAppLoading: true
});
setDelayLoad(false);
}
} else {
// app资源加载完成时,其他app能加载资源缓存,delayLoad为false
setDelayLoad(false);
}
} else {
// onChange时
if (state.firstMounted || !state.hasAppLoading) {
setDelayLoad(false);
}
}
}, true);
return function () {
actions.offGlobalStateChange();
};
});
var newProps = _extends({}, props, {
mfAppConfig: _extends({}, props.mfAppConfig, {
singular: true,
delayLoad: delayLoad
})
});
return MfApp(newProps);
}
/**
* single-SPA生命周期钩子,只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
var bootstrap = function bootstrap(props) {
var packageName = props.packageName,
startAppName = props.startAppName;
console.log("[" + packageName + "] app bootstraped. startAppName:", startAppName);
};
/**
* single-SPA生命周期钩子,应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
var mount = function mount(props) {
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
restoreState = props.restoreState,
params = props.params,
callbacks = props.callbacks,
Root = props.render;
console.log("[" + packageName + "] app mounted. startAppName:", startAppName, props);
ReactDOM__default['default'].render( /*#__PURE__*/React__default['default'].createElement(Root, {
startAppName: startAppName,
initData: restoreState,
params: params,
callbacks: callbacks
}), container ? container.querySelector("#" + targetDomId) : document.getElementById(targetDomId));
};
/**
* single-SPA生命周期钩子,应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
var unmount = function unmount(props) {
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
onSaveState = props.onSaveState,
state = props.state;
console.log("[" + packageName + "] app unmount. startAppName:", startAppName);
if (startAppName && state && onSaveState) {
var _state$get;
(_state$get = state.get(startAppName)) == null ? void 0 : _state$get.filter(function (value, key) {
return key.startsWith('AppLoader');
}).take(1).forEach(function (value) {
onSaveState(value.get('data').toJS());
});
}
var element = container ? container.querySelector("#" + targetDomId) : document.getElementById(targetDomId);
element && ReactDOM__default['default'].unmountComponentAtNode(element);
};
/**
* single-SPA可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
var update = function update(props) {
var _container$firstEleme;
var packageName = props.packageName,
targetDomId = props.targetDomId,
container = props.container,
startAppName = props.startAppName,
restoreState = props.restoreState,
params = props.params,
callbacks = props.callbacks,
Update = props.render;
console.log("[" + packageName + "] app update. startAppName:", startAppName);
var element = (container == null ? void 0 : (_container$firstEleme = container.firstElementChild) == null ? void 0 : _container$firstEleme.querySelector("#" + targetDomId)) || document.getElementById(targetDomId);
ReactDOM__default['default'].render( /*#__PURE__*/React__default['default'].createElement(Update, {
startAppName: startAppName,
initData: restoreState,
params: params,
callbacks: callbacks
}), element);
};
var lifecycle = /*#__PURE__*/Object.freeze({
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
});
exports.MfApp = MfApp;
exports.SingularMfApp = SingularMfApp;
exports.lifecycle = lifecycle;
Object.defineProperty(exports, '__esModule', { value: true });
})));
import React, { useState, useRef, useCallback, useEffect } from 'react';
import { addGlobalUncaughtErrorHandler, loadMicroApp, removeGlobalUncaughtErrorHandler } from 'qiankun';
import { addGlobalUncaughtErrorHandler, loadMicroApp, removeGlobalUncaughtErrorHandler, initGlobalState, runAfterFirstMounted } from 'qiankun';
import ReactDOM from 'react-dom';
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, basedir, module) {
return module = {
path: basedir,
exports: {},
require: function (path, base) {
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
}
}, fn(module, module.exports), module.exports;
}
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}
var _extends_1 = createCommonjsModule(function (module) {
function _extends() {
module.exports = _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _extends.apply(this, arguments);
}
module.exports = _extends;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var _extends = /*@__PURE__*/getDefaultExportFromCjs(_extends_1);
var STYLE_APP = {

@@ -31,3 +75,3 @@ width: '100%',

};
function mfApp(props) {
function MfApp(props) {
var mfAppConfig = props.mfAppConfig;

@@ -37,4 +81,4 @@ var name = mfAppConfig.name,

startAppName = mfAppConfig.startAppName,
_mfAppConfig$delayLoa = mfAppConfig.delayLoading,
delayLoading = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
_mfAppConfig$delayLoa = mfAppConfig.delayLoad,
delayLoad = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
params = mfAppConfig.params,

@@ -44,6 +88,6 @@ callbacks = mfAppConfig.callbacks,

restoreState = mfAppConfig.restoreState,
_mfAppConfig$singular = mfAppConfig.singular,
singular = _mfAppConfig$singular === void 0 ? true : _mfAppConfig$singular,
singular = mfAppConfig.singular,
RenderLoading = mfAppConfig.renderLoading,
RenderError = mfAppConfig.renderError;
console.log('mount startAppName', startAppName);

@@ -80,3 +124,3 @@ var _useState = useState(true),

if (delayLoading) {
if (delayLoad) {
return;

@@ -123,16 +167,10 @@ }

var status = (_appRef$current = appRef.current) == null ? void 0 : _appRef$current.getStatus();
if ('MOUNTED' === status) {
var _appRef$current2;
(_appRef$current2 = appRef.current) == null ? void 0 : _appRef$current2.unmount();
}
console.log('unmount startAppName', startAppName);
(_appRef$current = appRef.current) == null ? void 0 : _appRef$current.safeUnmount();
removeGlobalUncaughtErrorHandler(errorHandler);
};
}, [mfAppConfig, delayLoading]);
}, [mfAppConfig, delayLoad]);
return /*#__PURE__*/React.createElement("div", {
style: STYLE_APP
}, (delayLoading || loading) && RenderLoading ? /*#__PURE__*/React.createElement("div", {
}, (delayLoad || loading) && RenderLoading ? /*#__PURE__*/React.createElement("div", {
style: STYLE_APP_SPIN

@@ -152,2 +190,65 @@ }, /*#__PURE__*/React.createElement(RenderLoading, {

}));
} // 初始化 state
var actions = initGlobalState({
// 所有app资源加载状态
hasAppLoading: false,
// 第一个app挂载完成状态
firstMounted: false
});
/**
* 单实例场景,单实例指的是同一时间只会渲染一个微应用
*/
function SingularMfApp(props) {
// 当前app加载状态
var _useState5 = useState(true),
delayLoad = _useState5[0],
setDelayLoad = _useState5[1];
useEffect(function () {
// 第二个参数为true时,调用该函数就马上执行回调,此时state === prev,可进行初始化。
actions.onGlobalStateChange(function (state, prev) {
if (state === prev) {
// 初始化
if (!state.firstMounted) {
// 第一个app未挂载,则监听微应用生命周期
runAfterFirstMounted(function () {
actions.setGlobalState({
hasAppLoading: false,
firstMounted: true
});
}); // 无app在加载,当前app进入加载状态
if (!state.hasAppLoading) {
actions.setGlobalState({
hasAppLoading: true
});
setDelayLoad(false);
}
} else {
// app资源加载完成时,其他app能加载资源缓存,delayLoad为false
setDelayLoad(false);
}
} else {
// onChange时
if (state.firstMounted || !state.hasAppLoading) {
setDelayLoad(false);
}
}
}, true);
return function () {
actions.offGlobalStateChange();
};
});
var newProps = _extends({}, props, {
mfAppConfig: _extends({}, props.mfAppConfig, {
singular: true,
delayLoad: delayLoad
})
});
return MfApp(newProps);
}

@@ -177,3 +278,3 @@

Root = props.render;
console.log("[" + packageName + "] app mounted. startAppName:", startAppName);
console.log("[" + packageName + "] app mounted. startAppName:", startAppName, props);
ReactDOM.render( /*#__PURE__*/React.createElement(Root, {

@@ -200,3 +301,5 @@ startAppName: startAppName,

if (startAppName && state && onSaveState) {
state.get(startAppName).filter(function (value, key) {
var _state$get;
(_state$get = state.get(startAppName)) == null ? void 0 : _state$get.filter(function (value, key) {
return key.startsWith('AppLoader');

@@ -237,9 +340,9 @@ }).take(1).forEach(function (value) {

var lifecycle = /*#__PURE__*/Object.freeze({
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
});
export { lifecycle, mfApp };
export { MfApp, SingularMfApp, lifecycle };

@@ -14,2 +14,46 @@ 'use strict';

function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, basedir, module) {
return module = {
path: basedir,
exports: {},
require: function (path, base) {
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
}
}, fn(module, module.exports), module.exports;
}
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}
var _extends_1 = createCommonjsModule(function (module) {
function _extends() {
module.exports = _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _extends.apply(this, arguments);
}
module.exports = _extends;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var _extends = /*@__PURE__*/getDefaultExportFromCjs(_extends_1);
var STYLE_APP = {

@@ -41,3 +85,3 @@ width: '100%',

};
function mfApp(props) {
function MfApp(props) {
var mfAppConfig = props.mfAppConfig;

@@ -47,4 +91,4 @@ var name = mfAppConfig.name,

startAppName = mfAppConfig.startAppName,
_mfAppConfig$delayLoa = mfAppConfig.delayLoading,
delayLoading = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
_mfAppConfig$delayLoa = mfAppConfig.delayLoad,
delayLoad = _mfAppConfig$delayLoa === void 0 ? false : _mfAppConfig$delayLoa,
params = mfAppConfig.params,

@@ -54,6 +98,6 @@ callbacks = mfAppConfig.callbacks,

restoreState = mfAppConfig.restoreState,
_mfAppConfig$singular = mfAppConfig.singular,
singular = _mfAppConfig$singular === void 0 ? true : _mfAppConfig$singular,
singular = mfAppConfig.singular,
RenderLoading = mfAppConfig.renderLoading,
RenderError = mfAppConfig.renderError;
console.log('mount startAppName', startAppName);

@@ -90,3 +134,3 @@ var _useState = React.useState(true),

if (delayLoading) {
if (delayLoad) {
return;

@@ -133,16 +177,10 @@ }

var status = (_appRef$current = appRef.current) == null ? void 0 : _appRef$current.getStatus();
if ('MOUNTED' === status) {
var _appRef$current2;
(_appRef$current2 = appRef.current) == null ? void 0 : _appRef$current2.unmount();
}
console.log('unmount startAppName', startAppName);
(_appRef$current = appRef.current) == null ? void 0 : _appRef$current.safeUnmount();
qiankun.removeGlobalUncaughtErrorHandler(errorHandler);
};
}, [mfAppConfig, delayLoading]);
}, [mfAppConfig, delayLoad]);
return /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP
}, (delayLoading || loading) && RenderLoading ? /*#__PURE__*/React__default['default'].createElement("div", {
}, (delayLoad || loading) && RenderLoading ? /*#__PURE__*/React__default['default'].createElement("div", {
style: STYLE_APP_SPIN

@@ -162,2 +200,65 @@ }, /*#__PURE__*/React__default['default'].createElement(RenderLoading, {

}));
} // 初始化 state
var actions = qiankun.initGlobalState({
// 所有app资源加载状态
hasAppLoading: false,
// 第一个app挂载完成状态
firstMounted: false
});
/**
* 单实例场景,单实例指的是同一时间只会渲染一个微应用
*/
function SingularMfApp(props) {
// 当前app加载状态
var _useState5 = React.useState(true),
delayLoad = _useState5[0],
setDelayLoad = _useState5[1];
React.useEffect(function () {
// 第二个参数为true时,调用该函数就马上执行回调,此时state === prev,可进行初始化。
actions.onGlobalStateChange(function (state, prev) {
if (state === prev) {
// 初始化
if (!state.firstMounted) {
// 第一个app未挂载,则监听微应用生命周期
qiankun.runAfterFirstMounted(function () {
actions.setGlobalState({
hasAppLoading: false,
firstMounted: true
});
}); // 无app在加载,当前app进入加载状态
if (!state.hasAppLoading) {
actions.setGlobalState({
hasAppLoading: true
});
setDelayLoad(false);
}
} else {
// app资源加载完成时,其他app能加载资源缓存,delayLoad为false
setDelayLoad(false);
}
} else {
// onChange时
if (state.firstMounted || !state.hasAppLoading) {
setDelayLoad(false);
}
}
}, true);
return function () {
actions.offGlobalStateChange();
};
});
var newProps = _extends({}, props, {
mfAppConfig: _extends({}, props.mfAppConfig, {
singular: true,
delayLoad: delayLoad
})
});
return MfApp(newProps);
}

@@ -187,3 +288,3 @@

Root = props.render;
console.log("[" + packageName + "] app mounted. startAppName:", startAppName);
console.log("[" + packageName + "] app mounted. startAppName:", startAppName, props);
ReactDOM__default['default'].render( /*#__PURE__*/React__default['default'].createElement(Root, {

@@ -210,3 +311,5 @@ startAppName: startAppName,

if (startAppName && state && onSaveState) {
state.get(startAppName).filter(function (value, key) {
var _state$get;
(_state$get = state.get(startAppName)) == null ? void 0 : _state$get.filter(function (value, key) {
return key.startsWith('AppLoader');

@@ -247,10 +350,11 @@ }).take(1).forEach(function (value) {

var lifecycle = /*#__PURE__*/Object.freeze({
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
__proto__: null,
bootstrap: bootstrap,
mount: mount,
unmount: unmount,
update: update
});
exports.MfApp = MfApp;
exports.SingularMfApp = SingularMfApp;
exports.lifecycle = lifecycle;
exports.mfApp = mfApp;
{
"name": "@ttk/micro-frontend-react",
"version": "0.0.3",
"version": "0.0.4",
"description": "ttk微前端react",

@@ -15,3 +15,3 @@ "main": "./lib/index.js",

"test": "echo \"Error: no test specified\" && exit 1",
"build": "rollup -c"
"build": "rollup -c && cp -R es/index.js /Users/lztccol/FxProject/gitlab/src/ttk/website/node_modules/@ttk/micro-frontend-react/es"
},

@@ -26,3 +26,3 @@ "keywords": [

"peerDependencies": {
"qiankun": "^2.4.2",
"@ttk/micro-frontend-qiankun": "^0.0.1",
"react": "^16.13.1",

@@ -60,3 +60,3 @@ "react-dom": "^16.13.1",

"postcss": "^8.2.0",
"qiankun": "^2.4.2",
"@ttk/micro-frontend-qiankun": "^0.0.1",
"react": "^16.13.1",

@@ -63,0 +63,0 @@ "react-dom": "^16.13.1",

@@ -0,6 +1,85 @@

# @ttk/micro-frontend-react
提供应用qiankun微前端的react组件及相关生命周期API给TTK工程使用的依赖库
## 1.安装
```
npm install -s @ttk/micro-frontend-react qiankun
```
## License
```
yarn add @ttk/micro-frontend-react qiankun
```
## 2.API
### 2.1 mfApp
主工程加载单例子应用的组件,使用方式:
#### 2.1.1 ttk json工程
* component/index.js引入组件,
```
export { mfApp as MFApp } from '@ttk/micro-frontend-react'
```
* app详见本工程ttk-json-demo/ttk-edf-app-micro-frontend
#### 2.1.2 组件参数
* name: 子工程打包时output.library输出名称(一般可取package.json里的name),libraryTarget需要umd
* entry: 子应用访问url,
* startAppName:子应用指定的appName
* params: 父应用传给子应用的参数
* callbacks: 父应用传给子应用的回调
* restoreState:子应用unmount后,重新mount时,父应用传给子应用用于恢复的state
* onSaveState:父应用传给子应用的回调onSaveState,子应用unmount时,执行onSaveState,保存state到父应用
* renderLoading: 子应用加载过程中显示loading组件,不传不显示
* renderError: 子应用显示错误信息的组件,不传使用默认的
### 2.2 lifecycle
提供给@ttk/react框架(v4版本),作为微前端子应用工程的生命周期
```
import { lifecycle } from '@ttk/micro-frontend-react';
import { config as appLoaderConfig, start, render } from '@ttk/app-loader'
import { targetDomId, startAppName } from './constant'
import pack from '../package.json';
const { name: packageName } = pack;
/**
* single-SPA生命周期钩子,只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap(props) {
lifecycle.bootstrap(Object.assign({ targetDomId, packageName, startAppName }, props));
let { apps, init } = await import(/* webpackPreload: true */ './apps/index');
// appLoader配置
await appLoaderConfig(init({ apps }));
}
/**
* single-SPA生命周期钩子,应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props = {}) {
lifecycle.mount(Object.assign({ targetDomId, packageName, startAppName , render: start }, props))
}
/**
* single-SPA生命周期钩子,应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
lifecycle.unmount(Object.assign({ targetDomId, packageName, startAppName , state: window.reduxStore.getState() }, props));
}
/**
* single-SPA可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
lifecycle.update(Object.assign({ targetDomId, packageName, startAppName , render }, props));
}
```
* targetDomId为加载子应用容器元素的id,例如,应用容器元素为\<div id="app">\</div>,targetDomId为app
* startAppName为子应用指定的appName
* @ttk/app-loader的start, render分别为初始mount和update更新时的组件
* unmount生命周期中的参数state,传入全局state,用于获取startAppName的state,传给主工程进行保存
## 3.License
MIT License

@@ -7,0 +86,0 @@

import React, { useState, useEffect, useRef, useCallback } from 'react'
import { MicroApp, loadMicroApp, addGlobalUncaughtErrorHandler, removeGlobalUncaughtErrorHandler } from 'qiankun';
import { MicroApp, loadMicroApp, addGlobalUncaughtErrorHandler, removeGlobalUncaughtErrorHandler, runAfterFirstMounted, initGlobalState, MicroAppStateActions } from '@ttk/micro-frontend-qiankun';

@@ -21,3 +21,3 @@ const STYLE_APP = { width: '100%', height: '100%', overflow: 'hidden' };

startAppName: string,
delayLoading: boolean,
delayLoad: boolean,
params: any,

@@ -36,5 +36,5 @@ callbacks: any,

export function mfApp(props: MfAppProps) {
export function MfApp(props: MfAppProps) {
let { mfAppConfig } = props;
let { name, entry, startAppName, delayLoading = false, params, callbacks, onSaveState, restoreState, singular = true, renderLoading: RenderLoading, renderError: RenderError } = mfAppConfig;
let { name, entry, startAppName, delayLoad = false, params, callbacks, onSaveState, restoreState, singular, renderLoading: RenderLoading, renderError: RenderError } = mfAppConfig;

@@ -61,3 +61,3 @@ const [loading, setLoading] = useState(true);

}
if (delayLoading) {
if (delayLoad) {
return;

@@ -87,13 +87,10 @@ }

return () => {
const status = appRef.current?.getStatus();
if ('MOUNTED' === status) {
appRef.current?.unmount();
}
appRef.current?.safeUnmount();
removeGlobalUncaughtErrorHandler(errorHandler)
}
}, [mfAppConfig, delayLoading])
}, [mfAppConfig, delayLoad])
return (
<div style={STYLE_APP}>
{(delayLoading || loading) && RenderLoading ?
{(delayLoad || loading) && RenderLoading ?
<div style={STYLE_APP_SPIN}>

@@ -113,1 +110,50 @@ <RenderLoading loading={loading} />

}
// 初始化 state
const actions: MicroAppStateActions = initGlobalState({
// 所有app资源加载状态
hasAppLoading: false,
// 第一个app挂载完成状态
firstMounted: false,
});
/**
* 单实例场景,单实例指的是同一时间只会渲染一个微应用
*/
export function SingularMfApp(props: MfAppProps) {
// 当前app加载状态
const [delayLoad, setDelayLoad] = useState(true)
useEffect(() => {
// 第二个参数为true时,调用该函数就马上执行回调,此时state === prev,可进行初始化。
actions.onGlobalStateChange((state, prev) => {
if (state === prev) {
// 初始化
if (!state.firstMounted) {
// 第一个app未挂载,则监听微应用生命周期
runAfterFirstMounted(() => {
actions.setGlobalState({ hasAppLoading: false, firstMounted: true })
});
// 无app在加载,当前app进入加载状态
if (!state.hasAppLoading) {
actions.setGlobalState({ hasAppLoading: true })
setDelayLoad(false);
}
} else {
// app资源加载完成时,其他app能加载资源缓存,delayLoad为false
setDelayLoad(false);
}
} else {
// onChange时
if (state.firstMounted || !state.hasAppLoading) {
setDelayLoad(false)
}
}
}, true);
return function () {
actions.offGlobalStateChange();
}
});
const newProps = { ...props, mfAppConfig: { ...props.mfAppConfig, singular: true, delayLoad } };
return MfApp(newProps);
}

@@ -45,3 +45,3 @@ import React, { ReactElement } from "react";

if (startAppName && state && onSaveState) {
state.get(startAppName).filter((value: any, key: string) => key.startsWith('AppLoader'))
state.get(startAppName)?.filter((value: any, key: string) => key.startsWith('AppLoader'))
.take(1)

@@ -48,0 +48,0 @@ .forEach((value: any) => {