乐趣区

关于前端:浅谈微前端

一、微前端的概念

微前端(micro-frontends)并不是一项新的技术,而是一种浏览器端的架构理念. 微前端是一种多个团队通过独立公布性能的形式来独特构建现代化 web 利用的技术手段及办法策略。微前端的概念是由 ThoughtWorks 在 2016 年提出的,它借鉴了微服务的架构理念,外围在于将一个宏大的前端利用拆分成多个独立灵便的小型利用,每个利用都能够独立开发、独立运行、独立部署,再将这些小型利用交融为一个残缺的利用,或者将本来运行已久、没有关联的几个利用交融为一个利用。

二、微前端长处

1. 增量降级

  • 通过渐进式重构的伎俩和策略整合、降级、开发我的项目,解决不同技术栈对我的项目倒退的限度,防止齐全重写旧我的项目,采纳一一替换旧模块的形式按需降级。

    2. 简略、解耦的利用代码库

  • 对于开发人员来说代码更容易解藕、保护,防止了组件间耦合所导致的复杂性,每个前端利用能够只关注本人所须要实现的性能。

    3. 独立部署

  • 就像微服务一样,微前端的独立部署能力是要害,部署范畴越小,带来的上线危险越低。

    4. 业务自治

  • 遵循对立的接口标准进行零碎的集成,相互之间不存在依赖关系,不受技术栈限度,每个团队围绕业务性能垂直组建。

    三、微前端的多种实现形式

    1. iframe

  • iframe 虽不是为微前端而生,然而是集成的最简略形式之一。实质上来说,iframe 里的页面是齐全独立的,而且 iframe 还提供了很多的隔离机制,咱们只需将单体的前端利用,依照业务模块进行拆分,别离部署,最初通过 iframe 进行动静加载即可。

    <html>
    <head>
      <title> 微前端实现形式 -iframe</title>
    </head>
    <body>
      <h1> 来学习!</h1>
      <iframe id="frontend-container"></iframe>
      <script type="text/javascript">
        const routes = {
          '/': 'https://app.com/index.html',
          '/app1': 'https://app1.com/index.html',
          '/app2': 'https://app2.com/index.html',
        };
        const iframe = document.getElementById('frontend-container');
        iframe.src = routes[window.location.pathname];
      </script>
    </body>
    </html>
  • 长处:实现简略,运行稳固,人造具备隔离性。
  • 毛病:主页面和 iframe 共享最大容许的 HTTP 链接数,iframe 阻塞主页面加载,浏览器的后退按钮有效,性能低、通信简单、双滚动条、弹窗无奈全局笼罩,它的扩展性不高,只适宜简略的页面渲染。

2. 后端模版形式

  • 常见的实现形式是,服务端依据路由动静渲染特定页面的模板文件,将多个模板渲染到服务器上的 HTML 里,有一个 index.html,其中蕴含所有常见的页面元素,而后应用 include 来引入其余模板.
  • Html

    <html lang="en" dir="ltr">
    <head>
      <meta charset="utf-8">
      <title> 微前端实现形式 - 后端模版形式 </title>
    </head>
    <body>
      <h1> 来学习!</h1>
      <!--# include file="$PAGE.html" -->
    </body>
    </html>
  • Nginx

    server {
      listen 8080;
      server_name localhost;
      root /usr/share/nginx/html;
      index index.html;
      ssi on;
    
      # 将 / 重定向到 /app
      rewrite ^/$ http://localhost:8080/app redirect;
    
      # 依据门路拜访 html 
      location /app {set $PAGE 'app';}
      location /app1 {set $PAGE 'app1';}
      location /app2 {set $PAGE 'app2'}
    
      # 所有其余门路都渲染 /index.html
      error_page 404 /index.html;
    }
  • 长处:实现简略,技术栈独立。
  • 毛病:须要额定配置 Nginx,前后端拆散不彻底。

    3. npm 包形式

  • 将每个微前端封装公布为一个 npm 包,通过组件或者依赖形式引入。然而,这种办法意味着咱们每次开发新性能都必须从新编译并公布每个微前端利用,进行版本更新,每次版本公布须要告诉接入方同步更新。强烈不倡议应用这种微前端计划。
  • npm 包形式

    {
    "name": "@app/container",
    "version": "1.0.0",
    "description": "A web app",
    "dependencies": {
      "@app/app": "^1.0.1",
      "@app/app1": "^1.0.2",
      "@app/app2": "^1.0.3"
    }
    }
  • 长处:治理简略,性能兼容性好,部署开发可隔离。
  • 毛病:主利用和子利用之间版本更新存在强依赖关系,治理艰难。

    4. 引入 JS 形式

  • 这种形式是被采纳频率最高的一种办法。每个微前端都对应一个《script》标签,并且在加载时导出一个全局变量。而后,容器应用程序确定应该装置哪些微利用,并调用相干函数以告知微利用何时以及在何处进行渲染。与 package 集成不同,咱们能够用不同的 bundle.js 独立部署每个利用。与 iframe 集成不同的是,咱们具备齐全的灵活性,你能够用 JS 管制什么时候下载哪个利用,以及渲染利用时额定传参数。
  • 引入 JS 形式

    <html>
    <head>
      <title> 微前端实现形式 - 引入 JS 形式 </title>
    </head>
    <body>
      <h1> 来学习!</h1>
      <!-- 以下脚本不会马上渲染利用,而是别离裸露全局变量 -->
      <script src="https://app.com/bundle.js"></script>
      <script src="https://app1.com/bundle.js"></script>
      <script src="https://app2.com/bundle.js"></script>
      <div id="frontend-container"></div>
      <script type="text/javascript">
        // 以下全局函数是下面脚本裸露的
        const routes = {
          '/': window.renderApp,
          '/app1': window.renderApp1,
          '/app2': window.renderApp2,
        };
        const renderFunction = routes[window.location.pathname];
        // 渲染一个微利用
        renderFunction('frontend-container');
      </script>
    </body>
    </html>
  • 长处:灵便部署,独立开发。
  • 毛病:多个 js bundle 脚本的下载和执行会阻塞浏览器的解析。

    5. Web Component 形式

  • Web Component 是 JS 形式的一种办法的变体,每个微利用对应一个 HTML 自定义元素,供容器实例化,而不是提供全局函数。次要区别在于应用 Web Component 代替全局变量。然而 ShadowDom 的兼容性十分不好,一些前端框架在 ShadowDom 环境下无奈失常运行,尤其是 react 框架。
  • Web Component 形式

    <html>
    <head>
      <title> 微前端实现形式 -Web Component 形式 </title>
    </head>
    <body>
      <h1> 来学习!</h1>
      <!-- 以下脚本不会马上渲染利用,而是别离裸露全局变量 -->
      <script src="https://app.com/bundle.js"></script>
      <script src="https://app1.com/bundle.js"></script>
      <script src="https://app2/bundle.js"></script>
      <div id="frontend-container"></div>
      <script type="text/javascript">
        // 以下标签名是下面代码定义的
        const routes = {
          '/': 'micro-frontend-app',
          '/app1': 'micro-frontend-app1',
          '/app2': 'micro-frontend-app2',
        };
        const renderFunction = routes[window.location.pathname];
        // 渲染一个微利用(自定义标签)const root = document.getElementById('frontend-container');
        const webComponent = document.createElement(renderFunction);
        root.appendChild(webComponent);
      </script>
    </body>
    </html>
  • 长处:组件化开发,款式和元素隔离,灵便部署。
  • 毛病:多个 js bundle 脚本的下载和执行会阻塞浏览器的解析,ShadowDom 兼容性差,一些前端框架在 ShadowDom 环境下无奈失常运行。

小结

  • 微前端架构思维能够帮忙开发者解决一些业务倒退中的理论问题,不同的实现形式也各有利弊,对于每个业务来说,是否适宜应用微前端?如何正确的应用微前端?还须要通过利用场景,兼容范畴,系统集成指标,交互体验要求,部署能力,治理能力,开发能力等多方面综合剖析之后做出决策,目前业界曾经有不少框架来帮忙开发者轻松的集成微前端架构,下次将从框架及其具体的设计思维方向来进行学习。
退出移动版