首页 > 技术文章 > 共享模块:ModuleFederationPlugin

zcookies 2022-04-11 18:15 原文

ModuleFederationPlugin

  • webpack 5+ plugin
  • 在多个webpack构建应用中,实现模块共享:
    • Remote :提供共享模块 (提供者
    • Host : 消费共享模块 (消费者
  • 单个webpack 可以同时作为消费者和提供者,也可以只提供或只消费
//vue.config.js (示例)
module.exports = defineConfig({
    chainWebpack: (config) => {
    config
      .plugin("module-feaderation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          //作为输出的模块名,使用的时通过 ${name}/${expose} 的方式使用
          name: "app",
          // 构建输出的文件名
          filename: "remoteEntry.js",
          //作为 Host 时,去消费哪些 Remote ,如下消费other应用
          remotes: {
            other: "other@http://localhost:9002/remoteEntry.js",
          },
          //作为 Remote 时,export 哪些属性被消费,如下HelloWorld 被提供
          expose:{
              "./HelloWorld":'./src/components/HelloWorld.vue'
          },
           //可以提供的依赖,优先使用HOST的
          shared:['vue']
        },
      ]);
})
//应用示例
/**
*初始化两个项目 vue create app  vue create other
* 消费者:app
* 提供者:other
*/

//app vue.config.js
module.exports = defineConfig({
  chainWebpack: (config) => {
    config
      .plugin("module-feaderation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "app",
          filename: "remoteEntry.js",
          remotes: {
            other: "other@http://localhost:9002/remoteEntry.js",
          },
        },
      ]);
  },

  devServer: {
    port: 9001,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    },
  },
});


//other vue.config.js
module.exports = defineConfig({
  publicPath:'http://localhost:9002/',
  chainWebpack: (config) => {
    config
      .plugin("module-feaderation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "other",
          filename: "remoteEntry.js",
          exposes: {
            "./HelloWorld": "./src/components/HelloWorld.vue",
          },
        },
      ]);
  },
  devServer: {
    port: 9002,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    },
  }
});


// app 应用 src/components/views/HomeView.vue


<template>
  <div class="home">
    <hello-world msg="121221123"></hello-world>
  </div>
</template>

<script lang="ts">
import { defineAsyncComponent, defineComponent, onMounted } from 'vue';
export default defineComponent({
  name: 'HomeView',
  components: {
    //引用远程组件
    HelloWorld: defineAsyncComponent(() => import('other/HelloWorld')),
  }
});
</script>

推荐阅读