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>