微前端实战心得-使用链接、iframe 和 Ajax

372 阅读3分钟

微前端实战心得-什么是微前端

之前我们讨论了什么是微前端,实际上使用微前端并不需要非常高深的技术。

你可以以链接的方式将两个页面连接起来,可以通过 iframe 将一个片段集成到一个页面中。

链接

使用 a标签 <a href="https://example.com/xxx"></a> 连接不同页面。

为了保证各团队间的链接不会冲突,需要在一开始做出约定,如规定前缀:

商品团队:example.com/product/xxx

订单团队:example.com/order/xxx

这样下来,可以一目了然 /product 前缀的的链接归属于商品团队,而 /order 前缀链接归属于订单团队。各团队新增链接也要固定使用约定的前缀。

事实上,即使后续使用更复杂的微前端技术,不同团队之间的页面 URL 也是需要进行区分的,使用前缀区分是个好方式。

可以使用 Nginx 实现服务端路由配置

upstream team_product {
  server localhost:3001;
}
upstream team_order {
  server localhost:3002;
}
http {
  ...
  server {
    listen 80;
    ...
    location /product/ {
      proxy_pass http://team_product;
    }
    location /order/ {
      proxy_pass http://team_order;
    }
  }
}

优缺点

优点:

  • 如果不需要将一个团队的页面嵌入到另一个团队的页面中,那么使用链接将页面连接起来,不仅耦合性低,稳定性(鲁棒性)也很高。
  • 松散耦合:每个团队只需要关心自己的代码、部署等
  • 高鲁棒性:页面之间不会互相影响

缺点:

  • 不同团队之间代码冗余严重,页面之间可能都有相似的头部或者其他风格一致的模块。
  • 不同页面之间互相跳转会造成页面刷新,不如单个页面(如单页应用)响应迅速。

iframe

使用 iframe 能够将一个页面内嵌到另一个页面中,并且和链接一样具有松散的耦合和高鲁棒性。

<style>
iframe {
  border: 0;
  width: 100%;   // 和父元素一样宽
  height: 750px; // 固定高度
}
</style>
<iframe src="https://example.com/product/xxx"></iframe>

如果你使用的 React,可以用 react-frame-component (原理是使用了 React.createPortal)来将 React 组件 插入到 iframe 中。

优缺点

优点:

可以在所有浏览器中工作,脚本和样式不会和主文档相互影响,还具有许多安全特性。

缺点:

  • 布局约束

iframe 高度不能自动随内容撑开,可以使用 iframe-resizerMutationObserver

  • 性能开销

大量使用 iframe 对性能来说很糟糕,每个 iframe 都会创建一个新的浏览器上下文,会导致额外的内存和 CPU 消耗。

  • 破坏无障碍性

iframe 破坏了页面语义化,这对于无障碍访问工具很难理解。

  • SEO 不友好

搜索引擎会将外层页面和 iframe 作为两个不同页面进行索引。

Ajax

除了 iframe,自然的可以想到使用 Ajax 将一段代码片段插入页面中。

const element = document.querySelector('.product-recos') // 插入的元素
const url = element.getAttribute('data-url') // 从属性中拿到插入片段的 URL

window
  .fetch(url)
  .then(res => res.text())
  .then(html => element.innerHTML = html)

不同团队的代码在一个文档中,因此我们需要各种方式来隔离样式和 JavaScript

可以通过 css 选择器 class 添加命名空间前缀,或者使用 ShadowDOM 隔离样式。

对于 JavaScript,可以将脚本放在立即执行函数 IIFE 中,保证变量和函数不会添加到全局对象中。但是对于 cookiestorageevents 这些无法避免的全局变量,需要和 css 一样添加命名空间前缀

优缺点

优点

  • 自然的文档流
  • 搜索引擎和无障碍可访问性
  • 渐进式增强
  • 灵活的错误处理

缺点

  • 异步加载
  • 缺少隔离性
  • 需要向服务器发送请求
  • 脚本缺少生命周期

总结

链接和 iframe 都有完美的隔离性,并且不需要考虑兼容性,如果团队小并且后台系统不需要考虑 SEO,那么是非常完美的方案。

我在 2017 年时改造公司后台,将 PHP + Smarty 重构为 Vue 前后端分离时,就使用了 iframe 技术。当时还不知道“微前端”这个名词 😄。