微前端的架构实践和思考

424 阅读3分钟

micro-front-end

微前端的架构实践和思考Github

微前端到底是什么?

  • 一种架构风格,将可独立交付的前端应用程序组成一个更大的整体。
  • 多个团队开发的多个前端应用组合形成复杂平台类产品(感受就是一个SARS服务)

什么项目适合微前端架构?

  • 拆分巨型应用,使应用变得更加可维护
  • 兼容历史任务,实现增量开发

微前端架构的特点

  • 独立部署
  • 增量迁移
  • 团队自治
  • 松耦合代码

微前端架构方案

  • 自由组织模式
  • 基座模式
  • 去中心模式 (新项目推荐选择这个,旧项目迁移困难的推荐前两个)

自由组织模式(自主研发)

  • Iframe + postMessage
  • Systemjs模块化解决方案
  • 华为devCloud
    不提供统一的基座,通过机制和规范,让用户只感知到一个产品; 多个SPA组成的MPA, 每个菜单就是一个SPA,Header 菜单就是一个工程化的APP,提供公共能力,维护每个SPA的生命周期。

基座模式

  • Single-spa 微前端框架

  • 阿里的 qiankun
    qiankun 是一个基于 single-spa 的微前端实现库

去中心模式 (没有固定的基座,所有的微应用都可以相互引用;也可以选择某个应用作为中心)

  • webpack 5 ModuleFederationPlugin 模块联邦(微前端)

webpack 5 模块联邦示例

micro-react

  • root微应用和user微应用可以相互引用
  • 本示例 root微应用引入user微应用,user微应用也可以单独部署访问

使用

# 切换到user 根目录,安装依赖,并启动服务
yarn   
yarn start
# 访问地址:http://localhost:9001

# 切换到root 根目录,安装依赖,并启动服务
yarn
yarn start
# 访问地址:http://localhost:9000

技术细节

// root/webpack.config.js
// 模块联邦
const { ModuleFederationPlugin } = require('webpack').container

new ModuleFederationPlugin({
  name: 'roots',
  remotes: {
    microUser: 'microUser@http://localhost:9001/micro-user.js'
  }
})

// user/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container

new ModuleFederationPlugin({
  // 对外提供打包后的文件名,导入时会使用
  filename: 'micro-user.js',
  // 微应用的名字,类似single-spa 的组织名
  name: 'microUser',
  // 具体导出
  exposes: {
    // 名字:具体某个组件
    './user':'./src/User.js',
    './goods':'./src/Goods.js'
  }
})

// root/src/App.js
import React from 'react';
import User from './User'

const User2 = React.lazy(()=>import('microUser/user'))
const Goods = React.lazy(()=>import('microUser/goods'))

const App = () =>{
  return (
    <div>
      <h1>Webpack 5 联邦模块 + React17 的微前端实践</h1>
      <User/>
      <div style={{border: '1px solid #ccc', marginTop: '24px', padding: '12px'}}>
        <h3>来自其它微应用</h3>
        <React.Suspense fallback="loading app">
          <User2 />
          <Goods />
        </React.Suspense>
      </div>
    </div>
  )
}
export default App

micro-vue3

  • layout微应用和home微应用可以相互引用
  • 本示例 layout微应用引入home微应用,home微应用也可以单独部署访问

使用

# 切换到home 根目录,安装依赖,并启动服务
yarn   
yarn start
# 访问地址:http://localhost:9004

# 切换到layout 根目录,安装依赖,并启动服务
yarn
yarn start
# 访问地址:http://localhost:9003

技术细节

// home/webpack.config.js
// 模块联邦
const { ModuleFederationPlugin } = require('webpack').container

new ModuleFederationPlugin({
  name: 'home',
  filename: 'micro-home.js',
  remotes: {},
  exposes: {
    "./Content": "./src/components/Content",
    "./Button": "./src/components/Button"
  }
}),

// layout/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container

new ModuleFederationPlugin({
  name: 'layout',
  filename: 'micro-layout.js',
  remotes: {
    home: 'home@http://localhost:9004/micro-home.js'
  },
  exposes: {}
}),

// root/src/App.js
import React from 'react';
import User from './User'

const User2 = React.lazy(()=>import('microUser/user'))
const Goods = React.lazy(()=>import('microUser/goods'))

const App = () =>{
  return (
    <div>
      <h1>Webpack 5 联邦模块 + React17 的微前端实践</h1>
      <User/>
      <div style={{border: '1px solid #ccc', marginTop: '24px', padding: '12px'}}>
        <h3>来自其它微应用</h3>
        <React.Suspense fallback="loading app">
          <User2 />
          <Goods />
        </React.Suspense>
      </div>
    </div>
  )
}
export default App

思考与展望

  • 如何在 vue-cli 或者在 create-react-app 等cli 中使用webpack 5 的模块联邦?
  • 旧项目如何通过qiankun(或者single-spa) 重构成为一个微前端的项目?