微前端实战:大型前端应用的拆分与治理

卫衣 / 双肩包 / T 恤/羽绒服等任选,下单送 CSDN 年卡 程序员周边任选一款实物,直接赠送 CSDN 会员年卡+ Coding Plan,写代码学习装备一起拿下 立即抢购

"这个系统太庞大了,每次发布都提心吊胆..." 上个月的技术评审会上,我们团队正面临一个棘手的问题。一个运行了两年的企业级中后台系统,代码量超过 30 万行,构建时间长达 20 分钟,任何小改动都可能引发意想不到的问题。作为技术负责人,我决定是时候引入微前端架构了。

经过一个月的改造,我们成功将这个庞然大物拆分成多个独立应用,构建时间缩短到了 3 分钟,各个团队也能独立开发部署了。今天就来分享这次微前端改造的实战经验。

为什么选择微前端?

说实话,刚开始团队对微前端也有顾虑 - 会不会过度设计?性能会不会受影响?但当我们列出现有问题时,答案就很明显了:

// 原有的单体应用结构
const LegacyApp = {
  modules: {
    crm: {
      size: '12MB JS + 2MB CSS',
      team: 'A团队',
      updateFrequency: '每周2次'
    },
    erp: {
      size: '15MB JS + 3MB CSS',
      team: 'B团队',
      updateFrequency: '每天1次'
    },
    dashboard: {
      size: '8MB JS + 1MB CSS',
      team: 'C团队',
      updateFrequency: '每月2次'
    }
  },
  problems: {
    buildTime: '20min+',
    deployment: '全量发布',
    teamCollaboration: '代码冲突频繁',
    maintenance: '难以局部更新'
  }
}

架构设计与实现

1. 基座应用

首先,我们需要一个轻量级的基座应用来管理子应用:

// 基座应用 - App Shell
import { registerApplication, start } from 'single-spa'

// 注册子应用
const registerMicroApp = (name: string, entry: string) => {
  registerApplication({
    name,
    app: async () => {
      // 动态加载子应用
      const module = await System.import(entry)
      return module.default
    },
    activeWhen: location => {
      // 基于路由匹配激活子应用
      return location.pathname.startsWith(`/${name}`)
    }
  })
}

// 配置子应用
const microApps = [
  {
    name: 'crm',
    entry: '//localhost:3001/main.js',
    container: '#crm-container'
  },
  {
    name: 'erp',
    entry: '//localhost:3002/main.js',
    container: '#erp-container'
  },
  {
    name: 'dashboard',
    entry: '//localhost:3003/main.js',
    container: '#dashboard-container'
  }
]

// 注册所有子应用
microApps.forEach(app => registerMicroApp(app.name, app.entry))

// 启动微前端框架
start()

2. 子应用改造

每个子应用需要暴露生命周期钩子:

// 子应用入口
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { createStore } from './store'

// 导出生命周期钩子
export async function bootstrap() {
  console.log('CRM 应用启动中...')
}

export async function mount(props) {
  const { container, globalStore } = props
  const store = createStore(globalStore)

  ReactDOM.render(
    <Provider store={store}>
      <App />
    </Provider>,
    container
  )
}

export async function unmount(props) {
  const { container } = props
  ReactDOM.unmountComponentAtNode(container)
}

3. 通信机制

子应用间的通信是个关键问题,我们实现了一个事件总线:

// utils/eventBus.ts
class EventBus {
  private events = new Map<string, Function[]>()

  // 订阅事件
  on(event: string, callback: Function) {
    if (!this.events.has(event)) {
      this.events.set(event, [])
    }
    this.events.get(event)!.push(callback)

    // 返回取消订阅函数
    return () => {
      const callbacks = this.events.get(event)!
      const index = callbacks.indexOf(callback)
      callbacks.splice(index, 1)
    }
  }

  // 发布事件
  emit(event: string, data?: any) {
    if (!this.events.has(event)) return
    this.events.get(event)!.forEach(callback => {
      try {
        callback(data)
      } catch (error) {
        console.error(`Error in event ${event}:`, error)
      }
    })
  }
}

export const eventBus = new EventBus()

// 使用示例
// CRM 子应用
eventBus.emit('orderCreated', { orderId: '123' })

// ERP 子应用
eventBus.on('orderCreated', data => {
  updateInventory(data.orderId)
})

4. 样式隔离

为了避免样式冲突,我们采用了 CSS Modules 和动态 CSS 前缀:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[name]__[local]___[hash:base64:5]'
              }
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require('postcss-prefix-selector')({
                  prefix: '[data-app="crm"]'
                })
              ]
            }
          }
        ]
      }
    ]
  }
}

性能优化

微前端虽然解决了很多问题,但也带来了新的挑战,比如首屏加载性能。我们通过以下方式进行优化:

  1. 预加载策略:
// 基于路由预测用户行为
const prefetchApps = async () => {
  const nextPossibleApps = predictNextApps()

  // 预加载可能用到的子应用
  nextPossibleApps.forEach(app => {
    const script = document.createElement('link')
    script.rel = 'prefetch'
    script.href = app.entry
    document.head.appendChild(script)
  })
}
  1. 共享依赖:
// webpack.config.js
module.exports = {
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
    antd: 'antd'
  },
  // 使用 CDN 加载共享依赖
  scripts: ['https://unpkg.com/react@17/umd/react.production.min.js', 'https://unpkg.com/react-dom@17/umd/react-dom.production.min.js', 'https://unpkg.com/antd@4/dist/antd.min.js']
}

实践心得

这次微前端改造让我深刻体会到:

  1. 架构改造要循序渐进,先从边界清晰的模块开始
  2. 子应用拆分要基于业务边界,而不是技术边界
  3. 通信机制要简单可靠,避免复杂的状态同步
  4. 持续关注性能指标,及时发现和解决问题

最让我欣慰的是,改造后团队的开发效率明显提升,发布也更加灵活可控。正如那句话说的:"合久必分,分久必合。"在前端架构的演进中,找到当下最合适的平衡点才是关键。

写在最后

微前端不是银弹,它更像是一把双刃剑 - 使用得当可以解决很多问题,但也可能引入新的复杂性。关键是要根据团队和业务的实际情况,做出合适的选择。

有什么问题欢迎在评论区讨论,我们一起探讨微前端实践的更多可能!

如果觉得有帮助,别忘了点赞关注,我会继续分享更多架构实战经验~

前端巨型项目拆分整合原则方案 前端项目组织原则 微服务下的前端项目 ​ 随着微服务容器化技术的兴起,web项目变得不再像原来的单体应用项目那样庞大,通常以单一服务功能的实现为原则,服务端应用拆分成了一个个的互不依赖的小型项目。被拆分为独立服务的这些小型项目可以被独立的开发、测试、维护,部署,和版本迭代,不至于像原单体项目一样,因为任意模块的微小的变更而触发所有模块的重新上线流程。微服务时代的服务端应用不再以业务模块(条线)进行项目组织,而是被拆分为更细力度的微服务项目。基于容器化平台部署体系(paas),使得这些微服务项目组成的分布 阅读详情

相关推荐

微前端架构:如何实现大型前端项目的拆分整合

它借鉴了微服务的理念,将大型前端项目拆分成多个可独立开发、测试、部署的小型应用,再通过一定的机制将这些小型应用整合为一个完整的系统,从而实现大型前端项目的高效开发管理。本文围绕微前端架构展开,阐述其在大型前端项目拆分整合中的应用。对于企业和开发者来说,掌握微前端架构的相关知识和技能,将有助于更好地应对大型前端项目开发中的各种挑战,推动项目的顺利进行。微前端架构通过将大型前端项目拆分成多个独立的小型应用,并实现有效的整合,解决了传统单体架构存在的诸多问题,提高了开发效率和系统的可维护性。

2503_92849275的博客 1315

前端项目过大时,你是如何做拆分的?

通过这些拆分策略,可以大大提高前端项目的可维护性、可扩展性和开发效率。同时,也有助于团队成员之间的协作和代码复用。当前端项目过大时,拆分项目是一个很好的做法,可以提高代码的可维护性、可读性和可扩展性。

王铁柱666的博客 873

基于Vue的多项目整合实践

在笔者所在的前端开发团队中,采用前后端分离方案是在整个业务线稳定后进行的。业务前期主要采用后端套模板的方式,现阶段是采用基于Vue的单页开发模式。 这会出现一种情形,产品在不断迭代过程中,由于之前线上前端代码并非工程化项目,后面新需求多是另起Vue项目来进行编码上线,前端在整个业务线上没有统一的工程,项目过多分布散乱并且不易优化管理。(项目指根据新需求创建的项目代码,工程指一套代码下包含多个项目。...

weixin_34234829的博客 8578

当你的项目体积比较大?你如何做性能优化

Keep-Alive头对缩短浏览器和服务器之间的分布式请求的潜伏期是非常重要的,用户通过浏览器请求网页时,浏览器会读取服务器发送的特定的HTML文件,如果请求的页面中包含了外部的CSS和JavaScript文件,浏览器会再次发送独立的请求来获取这些文件,延长页面的加载时间。charset=utf-8">当一个网站一下子收到太多的HTTP请求,它的访客就会有响应时间延迟的体验,这不仅增加了CPU使用率也增加了页面的加载时间。浏览器具有缓存的功能,可以存储指定的文件,减少HTTP请求,从而提高网站的加载速度。

前端小99的博客 1982

微前端架构实战大型应用拆分治理之道

技术选型建议:interface TechStack {// 推荐使用// 特定场景考虑// 不推荐新项目: 'Module Federation',遗留系统: 'Single-spa',快速验证: 'Iframe'2. 拆分原则:// 按业务域拆分// 按团队拆分// 按更新频率拆分合理评估收益成本循序渐进地改造建立统一的技术标准重视团队协作有什么问题欢迎在评论区讨论,我们一起学习进步!

ChengFengTech的博客 627

微前端(一)微前端是什么?为什么要用微前端

微前端是什么? 参考网站: https://micro-frontends.org https://microfrontends.com 微前端就是多个可以独立发布功能的团队一起构建现代化web应用程序的技术、策略和方法,将大而可怕的事物分割成更小、更易于管理的部分,然后明确它们之间的依赖关系。我们的技术选择,我们的代码库,我们的团队,以及我们的发布过程都应该能够相互独立地操作和进化,而不需要过度的协调。微前端架构是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体

麦七的博客 2万+

千古前端微前端架构:大型应用拆分的完整指南

微前端架构是解决大型前端应用复杂性的终极方案,它允许将应用拆分为独立开发、测试和部署的小型模块,就像搭积木一样灵活组合。本文将带你了解微前端的核心概念、实施步骤和最佳实践,让你轻松掌握这一现代前端架构技术。 ## 为什么需要微前端架构? 随着前端项目规模扩大,传统单体应用会遇到诸多挑战:团队协作冲突、构建速度缓慢、技术栈锁定、部署风险高等。微前端架构借鉴后端微服务思想,将应用拆分为多个功能独立

gitblog_01037的博客 530

umi微前端实战:从模块联邦到应用拆分的完整解决方案

你是否正在面临这些开发困境?大型前端项目构建耗时越来越长,团队间代码冲突频繁,不同技术栈难以统一,每次上线都像是一场"冒险"?这些问题正是微前端架构要解决的核心痛点。本文将带你通过umi框架,从实际问题出发,一步步实现高效的微前端架构。 ## 痛点直击:为什么需要微前端? ### 真实开发场景的三大困境 **1. 构建性能瓶颈** - 项目代码量达到数十万行时,每次构建耗时超过10分钟 -

gitblog_00996的博客 422

什么是微前端?有哪些实现方案?

微前端架构的核心在于“拆分“集成”。它借鉴了后端开发中早已成熟的“微服务”理念,旨在将一个庞大、笨重的前端单体应用,拆解为一系列更小、更内聚、可独立开发、部署和维护的“微型应用”集合。微前端通过将应用拆分为多个自治的微应用,每个微应用都可以独立开发、测试、部署,并允许使用不同的技术栈 从而有效地解决了上述问题,显著提高了开发效率、可维护性、可扩展性和团队的自治能力。微前端作为一种先进的前端架构模式,在2025年已经非常成熟,它有效地解决了大型单体应用所面临的复杂性、协作瓶颈和技术僵化等核心问题。

破损的天堂鸟博客 1281

巨石应用终结者:万字长文带你从0到1落地微前端架构 (Module Federation实战)

微前端架构Module Federation实战摘要 本文深入探讨了微前端架构及其现代实现方案Module Federation,旨在解决巨石应用的四大痛点:技术债堆积、协作效率低下、部署困难、可扩展性瓶颈。文章分为理论解析和实战指导两部分。 理论部分系统梳理了微前端的发展历程:从iframe的简单隔离到single-spa的生命周期管理,再到qiankun的开箱即用方案,最终演进到Webpack 5的Module Federation(MF)方案。MF采用模块级共享机制,通过exposes/remote

2301_79858914的博客 977

有赞美业微前端的落地总结

JSON,获取入口文件 Hash,和当前项目的基础信息。基于上述配置生成内容,然后调用 Apollo 平台开放的 API 上传到 Apollo。如何进行多环境发布及服务链协作微应用发布环境主要分为测试、预发、生产。打包完成后,根据微前端构建平台指定环境。推送配置时候,指定 Apollo 对应的环境集群就好了。基座应用在运行时候,会根据环境 Apollo 交互对应环境集群的注册表信息。

2401_85599558的博客 1363

前端微服务实战大型应用拆分治理

微前端架构就像城市规划,需要统筹兼顾又要保持灵活。我们的经验是:合理分层 - 基座应用要足够稳定清晰边界 - 子应用之间要解耦统一规范 - 公共依赖要严格管理持续优化 - 性能问题要重点关注微前端不是银弹,它更像是一把双刃剑。使用得当可以大幅提升开发效率,但也会带来一定的复杂性。关键是要在架构设计时充分权衡,在实施过程中严格把控。有什么问题欢迎在评论区讨论,让我们一起探讨微前端架构的最佳实践!

ChengFengTech的博客 669

微前端入门及例子

英文原版链接:原文链接 引言 把前端做好很难,让多个团队同时开发大型前端应用,就更难了。目前有一种趋势是将前端应用拆分成更小、更易于管理的小应用。这种体系结构是如何提高前端团队的效率的呢? 本文将对这些问题进行阐述。除了讨论利弊,我们还将介绍一些可用的例子,并深入研究一个完整的示例应用。 近年来,微服务已迅速普及,许多组织都使用这种体系结构样式来避免大型单体应用的局限性。尽管有很多介绍微服务的文章,但还是有许多公司局限于单体式前端应用。 假设你想构建一个渐进式的Web应用程序,但是你很难将新的功能

Winne_Shen的专栏 1331

微前端简介

微前端 概念详解 什么是微前端微前端(Micro-Frontend),是将微服务(Micro-Services)理念应用前端技术后的 相关实践,使得一个前端项目能够经由多个团队独立开发以及独立部署。 01 微前端开发的特性 技术无关:各个开发团队都可以自行选择技术栈,不受同一项目中其它团队影 技术无关 响; 代码独立:各个交付产物都可以被独立使用,避免和其它交付产物耦合; 样式隔离:各个交付产物中的样式不会污染到其它组件; 原生支持:各个交付产物都可以⾃由使⽤浏览器原⽣ API,⽽⾮要求使⽤封装

CarrreyYan_979292的博客 1747

大型前端项目代码拆分:按业务模块 / 功能维度的实战思路

大型前端项目代码拆分:按业务模块 / 功能维度的实战思路

fruge365的博客 569

AI 辅助:微前端落地方案:别把组织问题全塞给框架

微前端适合团队自治和独立发布,但前提是业务边界清晰、治理规则明确。框架只能提供加载和隔离能力,不能替团队解决组织边界、依赖治理和发布责任。

weixin_49475940的博客 1072

什么是微前端

前言 其实在小企业里,我对微前端的概念一直很模糊,接触不到,所以只是一种概念性的认知,在这里记录下最近看的一篇文章总结。 微前端架构:旨在解决单体应用在一个相对长的时间跨度下,由于参的人员、团队的增加,从一个普通应用演变成一个巨石应用(Frontend Monolith),随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤为常见。 微前端要解决的问题 搞微前端目的就是要将产品...

Sophie_U的博客 657
上一篇: AI 辅助前端开发实战:让 AI 成为你的编程助手
下一篇: AI 聊天应用开发实战:从构思到上线的全栈开发指南
Ethan独立开发
博客等级 码龄2年 1065粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值