uniapp与微前端

# uniapp与微前端

# uniapp

# 微前端

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。其实,简单点来说就是:微前端是一种前端架构设计模式,其思想是将一个大型的前端应用拆分成多个独立的小型子应用,每个子应用都可以独立开发、构建、测试和部署,并且可以被组合成一个完整的前端应用

微前端是一种设计架构,并不是技术。是借鉴于微服务思想的设计架构,是一种为了解决庞大且难以维护的项目的方案。

  • 微前端解决了什么问题
  1. 大型应用程序的维护困难
  2. 大型应用程序的可扩展性问题
  3. 多团队协同开发问题
  • 微前端具备的核心价值
  1. 技术栈无关
  2. 独立开发、独立部署
  3. 增量升级
  4. 独立运行时
  • 微前端的优点
  1. 更好的代码可维护性
  2. 降低了开发的成本以及复杂性
  3. 更好的可重用性和可扩展性
  4. 更高的可靠性和安全性

微前端的缺点: 技术复杂度更高, 存在技术风险, 项目总体运行效率可能会变慢

# 微前端解决跨域的方案

  • Proxy

通过配置Web服务器反向代理,将多个前端应用程序转发到同一个主机的端口上。需要Nginx、Apache等服务器和一个负载均衡模块,允许所有的请求通过同一个域名和端口号对外访问。

  • iframe

我们可以通过iframe标签来解决主应用与子应用的跨域问题,主应用程序通过iframe标签嵌入子应用,并且使用postMessage来允许不同iframe元素之间进行通信。

  • CORS: "Access-Control-Allow-Origin": "*"

# 微前端架构方案

  • 自由组织模式

  • 基座模式

将多个子应用程序作为模块加载到一个主应用程序中。这些模块是独立的小型应用程序。每个子应用程序都可以独立开发、测试、部署,而主应用程序主要就是将子应用进行集成和协调,子应用程序发生变化,主应用程序也会自动的完成更新。

基座模式需要使用一些基础设施来支持子应用程序加载、路由和通信

Single-SPA (opens new window):一个支持多框架、多技术栈的JavaScript微前端框架,用于构建大型单页应用程序。

qiankun (opens new window):一个基于Single-SPA封装的微前端框架,支持React、Vue、Angular等技术栈。

  • 去中心化模式

是在多个子应用程序之间创建对等的关系,每个应用程序对应整个应用程序系统来说都是平等的。

# Single-SPA实践

# 创建主应用

npx create-single-spa

? Directory for new project wei-fe-spa # 项目名称
? Select type to generate single-spa root config # 创建微前端容器应用,根应用就是主应用,负责加载其他子应用,并作为单页应用(SPA)的容器。
? Which package manager do you want to use? pnpm # pnpm
? Will this project use Typescript? Yes # ts
? Would you like to use single-spa Layout Engine No # no
? Organization name (can use letters, numbers, dash or underscore) zhou # 组织名称

# 创建react子应用

cd wei-fe-spa

➜  wei-fe-spa git:(master) ✗ npx create-single-spa
? Directory for new project react-project # 子项目名称
? Select type to generate single-spa application / parcel # 微前端架构中的子应用程序,可以使用Vue、React、Angular框架,可以利用根应用提供的共享工具和服务进行通信。
? Which framework do you want to use? react # 选择框架
? Which package manager do you want to use? pnpm # pnpm
? Will this project use Typescript? Yes # ts
? Organization name (can use letters, numbers, dash or underscore) zhou # 组织名称
? Project name (can use letters, numbers, dash or underscore) react-project # 项目名称
  • 注册子应用
// wei-fe-spa/src/zhou-root-config.ts

// 注册子应用
registerApplication({
  name: "@zhou/react-project",
  app: () => System.import("@zhou/react-project"),
  activeWhen: ["/react-project"]
});
  • 声明导入配置:
// wei-fe-spa/src/index.ejs

<script type="systemjs-importmap">
{
    "imports": {
    "single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js",
    {/* 以cdn的形式导入react */}
    "react": "https://unpkg.com/react@17/umd/react.production.min.js",
    "react-dom": "https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"
    }
}
</script>


<% if (isLocal) { %>
  <script type="systemjs-importmap">
    {
      "imports": {
        "@zhou/root-config": "//localhost:9000/zhou-root-config.js",
        {/* 声明导入路径 */}
        "@zhou/react-project": "//localhost:9010/zhou-react-project.js" // 这个路径可以进入到子应用,直接 npm run start 启动子应用,在页面上即可看到~
      }
    }
  </script>
<% } %>

  • npm run start, 先启动子应用,再启动主应用

  • 访问主应用服务:http://localhost:9000,访问子应用服务:http://localhost:9000/react-project

# 创建vue子应用

➜  wei-fe-spa git:(master) ✗ npx create-single-spa
? Directory for new project vue-demo
? Select type to generate single-spa application / parcel
? Which framework do you want to use? vue
? Organization name (can use letters, numbers, dash or underscore) zhou

注册,配置跟上面的react一样~

# 创建公共模块子应用

跨应用通信

  • 创建:
➜  wei-fe-spa git:(master) ✗ npx create-single-spa
? Directory for new project utils
? Select type to generate in-browser utility module (styleguide, api cache, 
etc)  # 公共模块应用,非渲染组件,可以在不同应用之间共享JavaScript模块和组件。
? Which framework do you want to use? none
? Which package manager do you want to use? pnpm
? Will this project use Typescript? Yes
? Organization name (can use letters, numbers, dash or underscore) zhou
? Project name (can use letters, numbers, dash or underscore) utils
  • 导出函数:
// wei-fe-spa/utils/src/zhou-utils.ts

// 导出一个函数
export function addFn(a: number, b: number) {
    return a + b
}

  • 主应用中导入,跟上面的react一样,然后npm run start启动项目

这只是一个工具库,无需注册路由~

  • vue子应用中使用:
// wei-fe-spa/vue-demo/src/App.vue

mounted() {
    System.import('@zhou/utils').then(res => {
        console.log('res.addFn(1, 2)', res.addFn(1, 2))
    })
}

# qiankun

qiankun官网 (opens new window)

qiankun是一个基于Single-SPA的微前端解决方案,它可以帮我们将多个独立的前端应用整合到一个整体,并实现这些应用的共享和协同。

特性

  1. 基于single-spa封装,提供了更加开箱即用的API。
  2. 与技术栈无关,任意技术栈的应用均可使用/接入,不论是react、vue、angular还是其他框架。
  3. html entry接入方式,让你接入微应用像使用iframe一样简单。
  4. 样式隔离,确保微应用之间样式互相不干扰。
  5. js沙箱,确保微应用之间全局变量/事件不冲突。
  6. 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加快微应用打开速度。

Q:why not iframe?

如果不考虑体验问题,iframe 几乎是最完美的微前端解决方案了。

iframe 最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、js 隔离这类问题统统都能被完美解决。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题:

  1. url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
  2. UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中..
  3. 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
  4. 。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

其中有的问题比较好解决(问题1),有的问题我们可以睁一只眼闭一只眼(问题4),但有的问题我们则很难解决(问题3)甚至无法解决(问题2),而这些无法解决的问题恰恰又会给产品带来非常严重的体验问题, 最终导致我们舍弃了 iframe 方案。

Why Not Iframe (opens new window)

# 通信

  • 在主应用中进行注册的时候可以传递props参数;在子应用index.js文件中的mount生命周期中获取props参数
// 在主应用中进行注册的时候可以传递props参数:
registerMicroApps([
  {
    name: "reactApp",
    entry: "//localhost:3011",
    container: "#micro-app1",
    activeRule: "/micro-app1",
    props: {
      name: "青峰1",
    },
  },
  {
    name: "vueApp",
    entry: "//localhost:3012",
    container: "#micro-app2",
    activeRule: "/micro-app2",
    props: {
      name: "青峰2",
    },
  },
]);


// 子应用入口文件
export async function mount(props) {
  console.log("[react16] props from main framework", props);
  // 监听主应用传递的数据
  props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
  });

  // 向主应用传递数据
  // props.setGlobalState(state);
  render(props);
}

# 更改react配置

方案1:暴露webapck配置信息:react-scripts eject

会暴露所有配置信息

方案2:react-app-rewired (opens new window)

此工具可以在不 'eject' 也不创建额外 react-scripts 的情况下修改 create-react-app 内置的 webpack 配置,然后你将拥有 create-react-app 的一切特性,且可以根据你的需要去配置 webpack 的 plugins, loaders 等。

# 总结

微前端是指将前端应用程序拆分成更小的独立部分,然后将其组合成一个整体应用程序。这种架构方式可以使不同团队独立开发、部署和维护各自的功能模块,从而提高应用程序的可维护性、灵活性和可扩展性。

微前端未来的发展趋势将会是更加成熟化和标准化。目前还有一些痛点,例如多语言支持、子应用间通信、路由同步等问题需要解决。因此,微前端框架和相关工具的发展将会更加完善,提供更好的解决方案来解决这些问题。同时,由于微前端的高度灵活性,未来很有可能出现类似于微服务的组织模式,即更多的团队会提供独立的子应用来实现一些业务需求。

# 备注

  • 微前端解决的是隔离和通信,monorepo解决的是组件共享

# 参考

服务端发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放、chatgpt聊天消息发送就是这样的

上次更新: 1/15/2024, 1:36:41 AM
最近更新
01
taro开发实操笔记
09-29
02
前端跨端技术调研报告
07-28
03
Flutter学习笔记
07-15
更多文章>