微前端,这次我用webpack5来做

98 阅读1分钟

模块联邦理解

简单来说就是在A应用里能异步加载B应用的组件,可以在A应用中渲染。当然B应用也可以异步引用A应用的中组件,从而在B应用中渲染。模块联邦可以从多个应用中使用代码,从而创建一个完整的应用程序。

依赖关系图

1.png

  • 基于webpack5构建
  • host应用消费remote应用暴露出List的组件
  • remote应用消费host应用暴露出Home的组件
  • 多应用之间依赖相同版本的包可以通过 share scope 共享

代码验证

  • 创建host应用 2.png
// index.js

// 异步导入
import('./bootstrap.js')
// bootstrap.js

import React from 'react'
import ReactDOMClient  from 'react-dom/client'
import App from './App.js'

const root = ReactDOMClient.createRoot(document.getElementById('root'))

root.render(<App />)
// Home.js

import React from 'react'

const Header = () => {
  return <div>我是在host中的 Home 组件</div>
}

export default Header

// App.js

import React from 'react'
// 本地组件 Home
import Home from './Home.js'

// 消费remote中List组件。
const RemoteList = React.lazy(() => import('remote/List'))

const App = () => {
  return <div>
    <div>当前应用:host</div>
    <Home />
    <React.Suspense fallback="loading">
        <RemoteList />
    </React.Suspense>
  </div>
}

export default App

webpack.config.js配置

  devServer: {
    port: 1000
  },
  plugins: [
    // 模块联邦插件
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        // remote应用模块暴露出的文件入口
        remote: 'remote@http://localhost:1001/remoteEntry.js'
      },
      // const { dependencies } = require('./package.json')
      shared: dependencies
    })
  ],

  • 创建remote应用 项目架构和host应用基本一致。主要区别是webpack.config.js配置
devServer: {
   port: 1000
},
plugins: [
    // 模块联邦插件
    new ModuleFederationPlugin({
      name: 'remote',
      // 构建出的文件名 要和host中的remotes保持一致。
      filename: 'remoteEntry.js',
      exposes: {
        // 这里是暴露出的组件,可以给host消费。
        './List': './src/List.js'
      },
      // const { dependencies } = require('./package.json')
      shared: dependencies
    })
  ],
  • remote页面 7.png
  • host页面 8.png

Network

9.png