深入浅出模块联邦(2)

145 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

1.模块联邦使用场景

模块联邦的应用场景对于低代码这种模式特别适用,对于一个低代码平台一般是由一个画布平台+N个组件构成,如果想组件和平台抽离开来,一般处理的模式有在平台启动之前Vue.component类似的注册组件,这种模式具有的问题是平台更改热更新的时候,还是会将所有的内容打包在bundle.js中,如下图所示,使用模块联邦能够远程加载以后,就能把一些模块不打在bundle.js中。

image.png

2.强大化模块联邦

对于一个普通的模块联邦造成的问题是每次组件更新版本都需要去手动触发webpack的配置,然后再进行更改配置,进行重新打包。在此基础上,为了使模块联邦更加灵活。对于远程加载的组件包,我们采用一个中间件的方式,也就是平台(消费者)配置模块联邦的时候配置一个假路径,这个路径是一个服务器的地址,这个地址根据逻辑进行转发

3.实操

平台组件消费者(app_general)

配置如下,remotes本来指向的是远程组件的js地址,此处指向了一个远程服务器地址

  configureWebpack: {
    plugins: [
      new webpack.container.ModuleFederationPlugin({
        name: 'app_general',
        filename: 'remoteEntry.js',
        remotes: {
          app_exposes: 'app_exposes@http://localhost:5000/file',
        },
        shared: {
          vue: {
            singleton: true,
          },
        },
      }),
    ],
  },
组件暴露者(app_general)
<template>
  <div class="hello">
<button>我是远在服务器的按钮</button>
  </div>
</template>

然后将组件核心代码打包成一个静态lib.js

image.png

代理服务

这个远程服务器地址是本地起了一个express服务,这个服务将组件暴露者(app-expose)的打包后的js返回回来

const express = require('express')
const path = require("path");

const app = express()

app.use(express.static(path.join(__dirname,"../app-exposes/dist")));
app.get("/file",(req,res)=>{
     // 将一个文件作为响应内容返回给浏览器端。
    res.sendFile(path.join(__dirname,"../app-exposes/dist/remoteEntry.js"));
});


app.listen(5000,function(){
 
    console.log('express running at http://127.0.0.1:5000')
})

总结

通过代理服务的形式,我们可以在其中做很多逻辑,比如做一个版本控制器,通过代理服务切换组件代码版本。最终甚至可以达到的效果是,提供一个web配置平台,配置平台里面可以切换某个组件在某个项目的版本,这样达到可视化配置的情况