微前端

总结

0. 微应用

一种相互独立的前端应用程序组成一个更大的应用程序的架构风格。

1. 优点

2. 缺点

3. 集成方式

如何让这些独立的前端应用程序组成一个整体?

一定要有一个主应用,负责:

大概有5种方式来做集成:

3.1 服务端模版组合

根据请求的路由不同,在服务端组合模版、返回html资源到客户端。

3.2 build时集成

此时把各子应用程序作为一个包。主应用把它们作为依赖。打包主应用后,便能得到完整的应用程序。

3.3 iframe式运行时集成

其实这种方式可以算作是微前端的前身,iframe天然具有样式隔离、运行时隔离的特性。但iframe方式在交互、路由管理方面是有劣势的。

3.4 js式运行时集成

这种方式,把子应用的js入口文件引入到主应用,并暴露一系列声明周期函数让主应用去控制。这也是目前主流的集成方式。single-spa和基于single-spa的qiankun都是这种方式。

            
<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <!-- 暴露生命周期函数 -->
    <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">
      // 路由和入口函数的映射
      const microFrontendsByRoute = {
        '/': window.renderBrowseRestaurants,
        '/order-food': window.renderOrderFood,
        '/user-profile': window.renderUserProfile,
      };
      const renderFunction = microFrontendsByRoute[window.location.pathname];

      // 适时渲染特定的子应用到容器
      renderFunction('micro-frontend-root');
    </script>
  </body>
</html>
            
        

3.5 子应用定义成web components

这种方式把微应用作为一个自定义元素,需要把自定义元素的js定义引入。无需暴露生命周期函数,把微应用元素作为普通元素去操作。 MicroApp 是基于这种方式。

            
<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <!-- 每个js文件和自定义元素关联 -->
    <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">
      // 路由和自定元素的映射
      const webComponentsByRoute = {
        '/': 'micro-frontend-browse-restaurants',
        '/order-food': 'micro-frontend-order-food',
        '/user-profile': 'micro-frontend-user-profile',
      };
      const webComponentType = webComponentsByRoute[window.location.pathname];

      //适时将自定义元素渲染到容器
      const root = document.getElementById('micro-frontend-root');
      const webComponent = document.createElement(webComponentType);
      root.appendChild(webComponent);
    </script>
  </body>
</html>
            
        

4. 样式隔离

css天生就是全局的,行内样式又会让页面结构和表现混合。为了解决样式隔离的问题,社区想出了各种方式。这些方式都适用于微前端架构。

除了这些通用的解决方案,微前端架构还可以通过在主应用改写所有子应用的样式。比如子应用的所有类名加个属性选择器来做区分。qiankun就是这样做的。

            
div[data-qiankun="0000000000000000000"]{
    color: red;
}
        

参考链接