微前端架构常见框架

1. iframe

这里指的是每个微应用独立开发部署,通过 iframe 的方式将这些应用嵌入到父应用系统中,几乎所有微前端的框架最开始都考虑过 iframe,但最后都放弃,或者使用部分功能,原因主要有:

  • url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。

  • UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 frame 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器重置大小时自动居中。

  • 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。

  • 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

2. single-spa

single-spa 是一个基础的微前端框架,通俗点说,提供了生命周期的概念,并负责调度子应用的生命周期 挟持 url 变化事件和函数,url 变化时匹配对应子应用,并执行生命周期流程,完整的生命周期流程为:

2.1. Root Config

index.html:静态资源、子应用入口声明。

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Polyglot Microfrontends</title>
  <meta name="importmap-type" content="systemjs-importmap" />
  <script type="systemjs-importmap" src="https://storage.googleapis.com/polyglot_microfrontends.app/importmap.json"></script>
  <!-- if (isLocal) { -->
  <script type="systemjs-importmap">
    {
      "imports": {
        "@polyglot-mf/root-config": "/localhost:9000/polyglot-mf-root-config.js"
      }
    }
  </script>
  <!-- } -->
  
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/import-map-overrides.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/system.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/extras/amd.min.js"></script>
</head>
<body>
  <script>
    System.import('@polyglot-mf/root-config');
    System.import('@polyglot-mf/styleguide');
  </script>
  <import-map-overrides-full show-when-local-storage="devtools" dev-libs></import-map-overrides-full>
</body>
</html>

main.js:子应用注册及启动。

// main.js

import { registerApplication, start } from "single-spa";

registerApplication({
  name: "@polyglot-mf/navbar",
  app: () => System.import("@polyglot-mf/navbar"),
  activeWhen: "/",
});

registerApplication({
  name: "@polyglot-mf/clients",
  app: () => System.import("@polyglot-mf/clients"),
  activeWhen: "/clients",
});

registerApplication({
  name: "@polyglot-mf/account-settings",
  app: () => loadWithoutAMD("@polyglot-mf/account-settings"),
  activeWhen: "/settings",
});

start();

// A lot of angularjs libs are compiled to UMD, and if you don't process them with webpack
// the UMD calls to window.define() can be problematic.
function loadWithoutAMD(name) {
  return Promise.resolve().then(() => {
    let globalDefine = window.define;
    delete window.define;
    return System.import(name).then((module) => {
      window.define = globalDefine;
      return module;
    });
  });
}

single-spa提倡在浏览器中直接使用微前端应用,而不是通过构建工具进行打包。在single-spa中,参考的是SystemJS的思路,从而支持在浏览器中使用import、export。其实通过构建工具也可以实现类似的功能,webpack 可以将 ES6 的模块语法转换为浏览器可以理解的格式,并进行打包和优化。

2.2. single-spa-layout

指定single-spa在index.html中哪里渲染指定的子应用,constructApplications,constructRoutes及constructLayoutEngine 是针对定义的layout中的元素获取属性,再批量注册。

<html>

<head>
    <template id="single-spa-layout">
        <single-spa-router>
            <nav class="topnav">
                <application name="@organization/nav"></application>
            </nav>
            <div class="main-content">
                <route path="settings">
                    <application name="@organization/settings"></application>
                </route>
                <route path="clients">
                    <application name="@organization/clients"></application>
                </route>
            </div>
            <footer>
                <application name="@organization/footer"></application>
            </footer>
        </single-spa-router>
    </template>

    <script>

        // 注册
        import { registerApplication, start } from 'single-spa';
        import {constructApplications,constructRoutes,constructLayoutEngine} from 'single-spa-layout';

        // 获取routes
        const routes = constructRoutes(document.querySelector("#single-spa-layout"));

        // 获取所有的子应用
        const applications = constructApplications({
            routes,
            loadApp({ name }) {
                return System.import(name); // SystemJS 引入入口JS
            },
        });

        // 生成LayoutEngine
        const layoutEngine = constructLayoutEngine(routes, applications);

        // 批量注册子应用
        applications.forEach(registerApplication);

        // 启动主应用
        start();

    </script>

</head>

</html>

2.3. 子应用注册

single-spa针对子应用不同类型的子应用(如Vue、React等)都进行封装,但核心还是bootstrap、mount、unmount生命周期钩子。

import SubApp from './index.tsx'

export const bootstrap = () => {}

export const mount = () => {
  // 使用 React 来渲染子应用的根组件
  ReactDOM.render(<SubApp />, document.getElementById('root'));
}

export const unmount = () => {}

2.4. 样式隔离

提供子应用CSS的引入和移除:single-spa-css

// 代码块
import singleSpaCss from 'single-spa-css';

const cssLifecycles = singleSpaCss({
  // 这里放你导出的 CSS,如果 webpackExtractedCss 为 true,可以不指定
  cssUrls: ["https://example.com/main.css"],

  // 是否要使用从 Webpack 导出的 CSS,默认为 false
  webpackExtractedCss: false,

  // 是否 unmount 后被移除,默认为 true
  shouldUnmount: true,

  // 超时,不废话了,都懂的
  timeout: 5000
})

const reactLifecycles = singleSpaReact({...})

// 加入到子应用的 bootstrap 里
export const bootstrap = [
  cssLifecycles.bootstrap,
  reactLifecycles.bootstrap
]

export const mount = [
  // 加入到子应用的 mount 里,一定要在前面,不然 mount 后会有样式闪一下的问题
  cssLifecycles.mount,
  reactLifecycles.mount
]

export const unmount = [
  // 和 mount 同理
  reactLifecycles.unmount,
  cssLifecycles.unmount
]

子应用间CSS样式隔离,推荐使用scoped CSS和shadowDOM.

2.5. JS隔离

给每个子应用添加全局变量,加入时添加,移除是去除:single-spa-leaked-globals.

// 代码块
import singleSpaLeakedGlobals from 'single-spa-leaked-globals';

// 其它 single-spa-xxx 提供的生命周期函数
const frameworkLifecycles = ...

const leakedGlobalsLifecycles = singleSpaLeakedGlobals({
  globalVariableNames: ['$', 'jQuery', '_'], // 新添加的全局变量
})

export const bootstrap = [
  leakedGlobalsLifecycles.bootstrap, // 放在第一位
  frameworkLifecycles.bootstrap,
]

export const mount = [
  leakedGlobalsLifecycles.mount, // mount 时添加全局变量,如果之前有记录在案的,直接恢复
  frameworkLifecycles.mount,
]

export const unmount = [
  leakedGlobalsLifecycles.unmount, // 删掉新添加的全局变量
  frameworkLifecycles.unmount,
]
<
内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
资 源 简 介 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系, 详 情 说 明 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。 本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系,在此基础上重点分析了一种快速ICA实现算法一FastICA。物质的非线性荧光谱信号可以看成是由多个相互独立的源信号组合成的混合信号,而这些独立的源信号可以看成是光谱的特征信号。为了更好的了解光谱信号的特征,本文利用独立分量分析的思想和方法,提出了利用FastICA算法提取光谱信号的特征的方案,并进行了详细的仿真实验。 此外,我们还进行了进一步的研究,探索了其他可能的ICA应用领域,如音乐信号处理、图像处理以及金融数据分析等。通过在这些领域中的实验和应用,我们发现ICA在提取信号特征、降噪和信号分离等方面具有广泛的潜力和应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾光远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值