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>