前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微前端的前世今生

微前端的前世今生

作者头像
星宇大前端
发布2021-03-15 22:04:42
6310
发布2021-03-15 22:04:42
举报
文章被收录于专栏:大宇笔记

知道微前端已经一段时间了,最近公司项目在膨胀,使用微前端技术迫在眉睫,研究了半个月总结下所看所想。

前端为什么不能有微服务?


刚转到前端的时候,我就带着这个疑问。

做后端的时候有微服务,每个微服务可以单独运行,通过注册中心拉起成为一个大项目。

做移动端的时候我们可以组件化,每个组件都可以是一个app单独运行,我们通过一个中间件将每个组件拉起,组合成想要的app。

到了前端难道我们只能通过npm打包的方式去集成吗?带着这个问题,我首先找到了IFrame。

为什么不是Iframe


iframe 应该是实现微前端的最简单,最高效的方案。这也不是一个新技术了,老熟人。说起Iframe估计有个吐槽大会才能吐槽完小细节,一些问题我们无法去优化。

如qiankun所举例:

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

然后我找了github的 micro-frontends ,顺藤摸到了一堆瓜。

什么是微前端


“微前端”一词最早于2016年底在ThoughtWorks Technology Radar中提出。它将微服务的概念扩展到了前端世界。当前的趋势是构建一个功能强大且功能强大的浏览器应用程序(也称为单页应用程序),该应用程序位于微服务架构之上。随着时间的流逝,通常由一个单独的团队开发的前端层会不断增长,并且变得更加难以维护。这就是我们所谓的Frontfront Monolith。

简而言之,微前端就是将大而可怕的东西切成更小、更易于管理的部分,然后明确它们之间的依赖关系。我们的技术选择、代码库、团队和发布流程都应该能够独立运行和演变,而不会过度协调。

目的显而易见,和后端微服务、移动端组件化是一样的。

  • 解耦合,不同团队开发不同模块
  • 增量更新
  • 独立部署
  • 提高复用

实现微前端的方法


鉴于上述定义相当松散,有许多方法可以合理地称为微前端。在本节中,我们将展示一些示例,并讨论它们的权衡。所有方法都出现了一个相当自然的架构——通常应用程序中的每个页面都有一个微前端,并且有一个容器应用程序,它:

渲染常见的页面元素,如页眉和页脚 解决身份验证和导航等跨领域问题 将各种微前端聚合到页面上,并告诉每个微前端何时何地呈现自己 一个网页,里面有围绕不同部分绘制的盒子。一个盒子包裹整个页面,将其标记为“容器应用程序”。另一个框包装了主要内容(但不包含全局页面标题和导航),将其标记为“浏览微前端”

1. 服务端模板集成

首先我们写一个index.html 文件,留下中间动态片段由服务端去渲染。

代码语言:javascript
复制
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Feed me</title>
  </head>
  <body>
    <h1>? Feed me</h1>
    <!--# include file="$PAGE.html" -->
  </body>
</html>

需要借助Nginx去配置$PAGE变量,在请求的时候重新匹配url

代码语言:javascript
复制
server {
    listen 8080;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html;
    ssi on;

    # Redirect / to /browse
    rewrite ^/$ http://localhost:8080/browse redirect;

    # Decide which HTML fragment to insert based on the URL
    location /browse {
      set $PAGE 'browse';
    }
    location /order {
      set $PAGE 'order';
    }
    location /profile {
      set $PAGE 'profile'
    }

    # All locations should render through index.html
    error_page 404 /index.html;
}

服务端渲染微服务通过后端分割业务来实现,也是可以分割代码的,针对于ssr模式开发而来。

2. 构建时集成

通过将不同业务进行打包,然后通过一个主应用将不同业务集合起来,类似于下面的package.json:

代码语言:javascript
复制
{
  "name": "@feed-me/container",
  "version": "1.0.0",
  "description": "A food delivery web app",
  "dependencies": {
    "@feed-me/browse-restaurants": "^1.2.3",
    "@feed-me/order-food": "^4.5.6",
    "@feed-me/user-profile": "^7.8.9"
  }
}

这种虽然实现了分治,不同团队开发不同部分,但是更新依赖过于麻烦,不能增量打包发版。

3. 运行时集成

(1) Iframe

通过iframe 来动态加载,老生常谈,不多赘述,看如下代码:

代码语言:javascript
复制
<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <iframe id="micro-frontend-container"></iframe>

    <script type="text/javascript">
      const microFrontendsByRoute = {
        '/': 'https://browse.example.com/index.html',
        '/order-food': 'https://order.example.com/index.html',
        '/user-profile': 'https://profile.example.com/index.html',
      };

      const iframe = document.getElementById('micro-frontend-container');
      iframe.src = microFrontendsByRoute[window.location.pathname];
    </script>
  </body>
</html>

(2)通过JavaScript进行运行时集成

这个方法可能是最灵活的方法,也是我们看到团队最常用的方法。每个微前端都使用

代码语言:javascript
复制
<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <!-- These scripts don't render anything immediately -->
    <!-- Instead they attach entry-point functions to `window` -->
    <script src="https://browse.example.com/bundle.js"></script>
    <script src="https://order.example.com/bundle.js"></script>
    <script src="https://profile.example.com/bundle.js"></script>

    <div id="micro-frontend-root"></div>

    <script type="text/javascript">
      // These global functions are attached to window by the above scripts
      const microFrontendsByRoute = {
        '/': window.renderBrowseRestaurants,
        '/order-food': window.renderOrderFood,
        '/user-profile': window.renderUserProfile,
      };
      const renderFunction = microFrontendsByRoute[window.location.pathname];

      // Having determined the entry-point function, we now call it,
      // giving it the ID of the element where it should render itself
      renderFunction('micro-frontend-root');
    </script>
  </body>
</html>

下面说到的qinkun、icestark 等微前端框架基本都是基于这个模式实现,原理如此。

(3)通过 web Components进行运行时集成

前提是web Components已经完善成熟,个人感觉这个应该可以试验玩一下,不太懂也不多说。

代码语言:javascript
复制
<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <!-- These scripts don't render anything immediately -->
    <!-- Instead they each define a custom element type -->
    <script src="https://browse.example.com/bundle.js"></script>
    <script src="https://order.example.com/bundle.js"></script>
    <script src="https://profile.example.com/bundle.js"></script>

    <div id="micro-frontend-root"></div>

    <script type="text/javascript">
      // These element types are defined by the above scripts
      const webComponentsByRoute = {
        '/': 'micro-frontend-browse-restaurants',
        '/order-food': 'micro-frontend-order-food',
        '/user-profile': 'micro-frontend-user-profile',
      };
      const webComponentType = webComponentsByRoute[window.location.pathname];

      // Having determined the right web component custom element type,
      // we now create an instance of it and attach it to the document
      const root = document.getElementById('micro-frontend-root');
      const webComponent = document.createElement(webComponentType);
      root.appendChild(webComponent);
    </script>
  </body>
</html>

微前端细节实现


除了概念架构,微前端的实现还有很多细节要走。

如图所示:

微前端的今生


微前端的需求也是越来越明显,像阿里云,腾讯云等大型PC站,业务也不可能是一个团队进行开发,这种分治、增量更新更加明显,开源了不少框架来自于他们。

阿里微前端开源架构

点击查看官网(主题不高亮 - -),阿里果然是开源先驱

美团微前端

微前端文章

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/03/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前端为什么不能有微服务?
  • 为什么不是Iframe
  • 什么是微前端
  • 实现微前端的方法
    • 1. 服务端模板集成
      • 2. 构建时集成
        • 3. 运行时集成
          • 微前端细节实现
          • 微前端的今生
            • 阿里微前端开源架构
              • 美团微前端
                • 微前端文章
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档