Module Federation
webpack 模塊聯(lián)邦 是webapck 5 提供的一個(gè)能力;下面只給出具體的配置;
環(huán)境:
- node v16.18.0
- npm 8.19.2
- vue-cli 5.0.8 (vueCli 5.x 才支持 webpack 5.x)
項(xiàng)目創(chuàng)建
- vue create app (app2) (選擇最基本的配置即可)
- 微調(diào)結(jié)構(gòu)
// bootstrap.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
// main.js
import('./bootstrap'); // 便于shared 共用依賴 (官方指導(dǎo))
啟動(dòng)服務(wù)冗疮,查看 http://localhost:4000/ 即可
以下放出具體配置
app
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;
module.exports = defineConfig({
transpileDependencies: true,
publicPath: 'http://localhost:4000/',
devServer: {
port: 4000,
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"
}
},
chainWebpack: config => {
// https://github.com/vuejs/vue-cli/issues/6318
config.optimization.delete('splitChunks');
config
.plugin('module-federation-plugin')
.use(ModuleFederationPlugin,[
{
name: 'app1', // 當(dāng)前APP作為remote暴露組件時(shí)的APP的名字
// library: 'app1remote', // 當(dāng)前APP作為remote暴露組件時(shí)的library名字
filename: 'remoteApp1Entry.js',
// 所有被暴露的組件會(huì)打包到這個(gè)文件中鸟雏,同理使用者也需要從這里引入
remotes: {
// app2: "app2_remote",
app2: "app2@http://localhost:5000/remoteApp2Entry.js",
// app_three: "app_three_remote"
}, // 定義該庫作為host時(shí)可能要引用的remote
// exposes: {
// 'AppContainer': './src/App',
// 'HelloContainer': './src/components/HelloWorld'
// }, // 定義該庫作為remote時(shí)陆盘,要暴露出去的組件流强。左邊是相對(duì)路徑和組件名字(其他庫使用時(shí)候)池凄,右邊是該組件在本庫內(nèi)的路徑
shared: require('./package.json').dependencies,
}
]
)
}
})
// App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<App2HelloContainer msg="Vue.js App2 test"/>
<!-- <App2Com /> -->
<AppContainer />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import AppContainer from 'app2/AppContainer';
const App2HelloContainer = () => import('app2/HelloContainer');
console.log('App2Com', App2HelloContainer); // yunt.Su
export default {
name: 'App',
components: {
HelloWorld,
// App2Com
App2HelloContainer,
AppContainer
}
}
</script>
app2
// vue.config.js
const { defineConfig } = require('@vue/cli-service');
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;
module.exports = defineConfig({
transpileDependencies: true,
publicPath: "http://localhost:5000/",
devServer: {
hot: true,
port: 5000,
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"
}
},
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: 'app2', // 當(dāng)前APP作為remote暴露組件時(shí)的APP的名字
library: {
type: 'var',
name: 'app2'
}, // 當(dāng)前APP作為remote暴露組件時(shí)的library名字
filename: 'remoteApp2Entry.js',
// 所有被暴露的組件會(huì)打包到這個(gè)文件中,同理使用者也需要從這里引入
remotes: {
// app_two: "app_two_remote",
// app_three: "app_three_remote"
}, // 定義該庫作為host時(shí)可能要引用的remote
exposes: {
'./AppContainer': './src/App.vue',
'./HelloContainer': './src/components/HelloWorld.vue'
}, // 定義該庫作為remote時(shí)争占,要暴露出去的組件。左邊是相對(duì)路徑和組件名字(其他庫使用時(shí)候)序目,右邊是該組件在本庫內(nèi)的路徑
// shared: ["react", "react-dom","react-router-dom"]// 和引入的組件公用的dependency
shared: require('./package.json').dependencies
})
]
},
chainWebpack: config => {
// https://github.com/vuejs/vue-cli/issues/6318
config.optimization.delete('splitChunks');
}
})