模块联邦技术
1. 概述
模块联邦技术是webpack5新增的功能,可以 实现多个应用之间的模块共享,提高代码复用率,减少代码冗余。
js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
不太像微前端,微前端是将多个应用拆分成多个子应用,每个子应用都是独立的应用,可以独立部署,独立开发,独立运行。
模块联邦是将多个应用拆分成多个模块,每个模块都是独立的,可以独立开发,独立运行,但是这些模块可以共享代码。
emp2.0是基于模块联邦技术实现的,emp2.0是一个基于webpack5的微前端解决方案。 emp2
2. 使用
bash
host
bootstrap.js
index.html
index.js
webpack.config.js
package.json
remote
bootstrap.js
index.html
index.js
webpack.config.js
package.json
list.js # 共享模块
核心代码,主要是使用webpack5 的 ModuleFederationPlugin 插件
提供方
js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
new ModuleFederationPlugin({
name: 'remote', //name必填
filename: 'remoteEntry.js', //filename必填 生成的文件名
exposes: {
'./addList': './list.js', //暴露的模块
},
}),
使用方
js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
new ModuleFederationPlugin({
name: 'host', //name必填
filename: 'hostEntry.js', //filename必填 生成的文件名
//对应关系remote对应的remote项目ModuleFederationPlugin的name 后面url对应的port以及对应ModuleFederationPlugin的filename
remotes: {
remote: 'remote@http://localhost:9001/remoteEntry.js', //引入模块
},
}),
打包的时候会通过cdn的方式加载远程的模块,然后在本地使用。
remote 模块暴露方
bootstrap.js
js
import { addList } from './list'
addList()
const app = document.getElementById('app')
app.innerHTML = `remote`
index.html
html
<body>
<div id="app"></div>
</body>
index.js
js
import('./bootstrap')
list.js 暴露出去的模块
js
// 这个模块会暴露给 host 项目 去使用
const wrap = document.createElement('div')
const list = [
{ name: '张三', age: 18 },
{ name: '李四', age: 19 },
{ name: '王五', age: 20 },
{ name: '赵六', age: 21 },
{ name: '孙七', age: 22 },
]
list.forEach((item) => {
const p = document.createElement('p')
p.innerHTML = `姓名:${item.name} 年龄:${item.age}`
wrap.appendChild(p)
})
export const addList = () => {
document.body.appendChild(wrap)
}
webpack.config.js
js
const { Configuration } = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
/**
* @type {Configuration} //配置智能提示
*/
const config = {
mode: 'none',
entry: './index.js',
output: {
filename: 'bundle.js',
},
devServer: {
port: 9001, //remote 9001
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
new ModuleFederationPlugin({
name: 'remote', //name必填
filename: 'remoteEntry.js', //filename必填 生成的文件名 http://localhost:9001/remoteEntry.js 是可以直接访问到暴露的模块的
exposes: {
'./addList': './list.js', //暴露的模块
},
}),
],
}
module.exports = config
package.json
json
{
"name": "remote",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.92.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4",
"html-webpack-plugin": "^5.6.0"
},
"keywords": [],
"author": "",
"license": "ISC"
}
host 模块使用方
bootstrap.js
js
import('remote/addList').then(({ addList }) => {
const app = document.getElementById('app')
app.innerHTML = `host`
addList()
})
index.html
html
<div id="app"></div>
index.js
js
import('./bootstrap')
webpack.config.js
js
const { Configuration } = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
/**
* @type {Configuration} //配置智能提示
*/
const config = {
mode: 'none',
entry: './index.js',
output: {
filename: 'bundle.js',
},
devServer: {
port: 9002, // host 9002
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
new ModuleFederationPlugin({
name: 'host', //name必填
filename: 'hostEntry.js', //filename必填 生成的文件名
//对应关系remote对应的remote项目ModuleFederationPlugin的name 后面url对应的port以及对应ModuleFederationPlugin的filename
remotes: {
remote: 'remote@http://localhost:9001/remoteEntry.js', //引入模块
},
}),
],
}
module.exports = config
package.json
json
{
"name": "host",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.92.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4",
"html-webpack-plugin": "^5.6.0"
},
"keywords": [],
"author": "",
"license": "ISC"
}