2、从0到1搭建前端微服务架构

127 阅读4分钟

——你以为只是拆个项目?其实是在养一群“独立小怪兽”


1. 引子:当项目变成一头怪兽

想象一下,你有一个前端项目,几百个页面,几千个组件,几百个接口调用。
每次改个小按钮,打包能打到天荒地老,发布一次像在下围棋,动一个角,崩一大片。

你崩溃了,老板也崩溃了。

于是,你听说了一个神奇的概念:

微前端(Micro Frontends)—— 把庞大的怪兽,分解成若干小怪兽,各自生活,各自成长。

听起来很酷,对吧?
实际上,更酷。


2. 什么是微前端?(Micro Frontends)

                  ┌────────────────────────┐
                  │        主应用 (Container)        │
                  │  - 全局路由控制                  │
                  │  - 公共组件(Header/Footer等)  │
                  └────────────────────────┘
                      ↓       ↓       ↓
    ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
    │  子应用1 (Remote1) │ │  子应用2 (Remote2) │ │  子应用3 (Remote3) │
    │  (独立打包部署)     │ │  (独立打包部署)     │ │  (独立打包部署)     │
    └─────────────┘ └─────────────┘ └─────────────┘

一句话解释:

把一个大前端应用拆分成多个小应用,每个小应用可以独立开发、独立部署、独立升级。

说白了,就是:

  • 开发团队可以互不打扰;
  • 不用再全量打包;
  • 某个业务坏掉了,其他还能正常跑;
  • 可以多种技术栈共存(比如React + Vue + 原生JS并肩作战)。

3. 为什么要搞微前端?(三大痛点)

痛点微前端解决方案
项目太大,开发体验差拆小,独立开发
打包慢,发布慢子应用独立构建部署
技术栈升级困难允许子应用用不同技术栈

简而言之:

微前端就是给大项目开了N条快车道,各自狂奔互不拖后腿。


4. 微前端主流技术方案

主要有三种流派:

技术方案代表特点
iframe模式纯浏览器原生支持简单粗暴,隔离性好,但体验差
JavaScript沙箱Single SPA灵活,粒度细,但自己要管理隔离
Webpack 5 Module FederationModule Federation真正的模块共享,最流行现代化方案

大厂实际用的,大多数是后两种。


5. 最主流实战:Module Federation 搭建微前端

现在,我们来实际搭建一个用 Module Federation 的微前端架构。

Module Federation 加载机制

子应用 Webpack 打包 → 生成 remoteEntry.js

主应用 (Container)
    ↓
动态拉取 remoteEntry.js
    ↓
加载远程模块(如Button组件)
    ↓
渲染到主应用页面

🏗️ 基本思路:

  1. 主应用(Container) :负责路由、子应用挂载。
  2. 子应用(Remote) :每个子应用独立开发、独立打包、独立部署。
  3. Module Federation插件:让主应用可以动态加载子应用的模块。

🔥 具体搭建步骤


【主应用配置】

webpack.config.js

javascript
复制编辑
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "container",
      remotes: {
        app1: "app1@http://localhost:3001/remoteEntry.js",
        app2: "app2@http://localhost:3002/remoteEntry.js"
      }
    })
  ]
};

👉 主应用通过remotes引入子应用。


【子应用配置】

webpack.config.js(子应用比如app1):

javascript
复制编辑
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "app1",
      filename: "remoteEntry.js",
      exposes: {
        './Button': './src/Button'
      }
    })
  ]
};

👉 子应用通过exposes暴露自己的模块,比如一个Button组件。


【主应用使用子应用模块】

比如,在主应用的某个地方:

javascript
复制编辑
import Button from 'app1/Button';

export default function HomePage() {
  return (
    <div>
      <h1>主应用首页</h1>
      <Button />
    </div>
  );
}

就像魔法一样,子应用的Button瞬间出现在了主应用页面上。

主应用和子应用的依赖关系图

主应用             子应用1         子应用2
  ↓                   ↓               ↓
React 17shared → React 17shared → React 17
Lodash 4.x ← shared → Lodash 4.x ← shared → Lodash 4.x
Antd 5.x    ← shared → Antd 5.x


6. 微前端要注意什么坑?

虽然微前端很酷,但也别头铁直接上,注意几个常见问题:

问题解决方法小Tips
样式污染使用Scoped CSS、CSS Modules每个子应用自带“防护罩”
公共依赖冲突配置shared依赖谁用谁负责,不抢资源
子应用挂了全盘崩加载容错处理出问题时优雅降级
跨应用通信混乱统一事件总线不要让小怪兽打群架
一句话:

微前端不是银弹,但踩对了点,是超神。


7. 最后的总结

  • 微前端,适合大型、多团队、多业务线的项目。
  • 小项目?不用搞,徒增复杂度。
  • 微前端最难的是整体架构设计+子应用治理规范,不是搭一两个Demo。

记住:

微前端不是为了炫技,而是为了让项目更健康地长大。


8. 彩蛋:一句话总结微前端

微前端 = “一群能独立作战的小怪兽,组成一支无敌战队。”

而你,作为架构师,就是那位召唤小怪兽的“训练师”。
(当然,不好好训练的话,项目还是会打起来的🤣)